内容简介:当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题结果:火车票会重复出售使用多线程之间同步synchronized或使用锁(lock)
当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题
模拟线程安全问题
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--;
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
垃圾回收算法手册:自动内存管理的艺术
Richard Jones、Eliot Moss、Antony Hosking / 王雅光、薛迪 / 机械工业出版社 / 2016-3 / 139
在自动内存管理领域,Richard Jones于1996年出版的《Garbage Collection:Algorithms for Automatic Dynamic Memory Management》可谓是一部里程碑式的作品。接近20年过去了,垃圾回收技术得到了非常大的发展,因此有必要将该领域当前最先进的技术呈现给读者。本书汇集了自动内存管理研究者和开发者们在过去50年间的丰富经验,在本书中......一起来看看 《垃圾回收算法手册:自动内存管理的艺术》 这本书的介绍吧!