当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题
模拟线程安全问题
public class SafeThread implements Runnable {
private int ticketCount = 50;
@Override
public void run() {
while (ticketCount > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
ticketCount--;
}
}
}
@RequestMapping("test-safe")
public void testSafe() {
SafeThread safeThread = new SafeThread();
Thread t1 = new Thread(safeThread, "thread-1");
Thread t2 = new Thread(safeThread, "thread-2");
t1.start();
t2.start();
}
结果:火车票会重复出售
解决办法
使用多线程之间同步synchronized或使用锁(lock)
1.同步代码块
public class SafeThread implements Runnable {
private int ticketCount = 50;
@Override
public void run() {
while (ticketCount > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
ticketCount--;
}
}
}
}
2.同步方法
public class SafeThread implements Runnable {
private int ticketCount = 50;
@Override
public void run() {
while (ticketCount > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
// synchronized (this) {
// System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
// ticketCount--;
// }
sale();
}
}
private synchronized void sale() {
System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
ticketCount--;
}
}
注意:同步函数使用this锁
3.静态同步函数
方法上加上static关键字,使用synchronized 关键字修饰或者使用类.class文件。
静态的同步函数使用的锁是该函数所属字节码文件对象
可以用 getClass方法获取,也可以用当前类名.class 表示
public class SafeThread implements Runnable {
private int ticketCount = 50;
@Override
public void run() {
while (ticketCount > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
// synchronized (this) {
// System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
// ticketCount--;
// }
// sale();
sale2();
}
}
private synchronized void sale() {
System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
ticketCount--;
}
private void sale2() {
synchronized (SafeThread.class) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (50 - ticketCount + 1) + "张票");
ticketCount--;
}
}
}
死锁问题
同步中嵌套同步,导致锁无法释放
解决办法:尽量避免同步中嵌套同步
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。