详解Java并发编程之volatile关键字
什么是volatile关键字?
volatile 是 Java 中一个非常重要的关键字,用于修饰变量,可以保证多个线程操作同一个变量时的可见性。当一个变量被 volatile 修饰时,线程每次对这个变量进行操作后,都会强制刷新本地缓存,使其他线程可以立即获取到最新的值。
volatile关键字的作用
volatile 可以保证多线程之间的可见性,防止多个线程操作同一变量时发生脏读,重复读,和读写颠倒的情况。使用 volatile 可以使线程在被阻塞时不会因为缓存数据的一致性问题导致死循环。
需要注意的是,volatile 并不能保证原子性。在多线程并发访问时,仅仅使用 volatile 是无法解决线程安全问题的。
volatile 和线程安全的实例说明
public class MyVolatileDemo {
volatile int num = 0;
public void increase() {
num++;
}
public static void main(String[] args) throws InterruptedException {
MyVolatileDemo demo = new MyVolatileDemo();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
demo.increase();
}
}).start();
}
Thread.sleep(5000);
System.out.println("num=" + demo.num); // 输出的 num 值不能保证一定是 5000,因为 volatile 仅能保证可见性,无法保证原子性,需要配合 synchronized 等线程安全工具一起使用。
}
}
上面这个例子中,我们创建了 5 个线程,每个线程对 num 变量调用 increase() 方法 1000 次,我们期望 num 的最终值应该是 5000,但是因为 volatile 并不保证原子性,所以输出结果并没有达到预期。
那么问题来了,怎样才能保证线程安全呢?可以使用 synchronized,把 increase() 方法加锁。
public class MyVolatileDemo {
int num = 0;
public synchronized void increase() {
num++;
}
public static void main(String[] args) throws InterruptedException {
MyVolatileDemo demo = new MyVolatileDemo();
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
demo.increase();
}
}).start();
}
Thread.sleep(5000);
System.out.println("num=" + demo.num); // 此时输出的 num 值始终为 5000,解决了线程安全问题。
}
}
总结
使用 volatile 变量可以保证线程之间的可见性,但是不能保证原子性。想要保证线程安全,需要使用到 synchronized 或者其他的线程安全工具,以保证多线程操作的原子性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java并发编程之volatile关键字 - Python技术站