Java多线程编程(5)volatile

2023-03-07  本文已影响0人  景知育德

volatile不保证原子性,但是保证了可见性、顺序性。
synchronized保证原子性、可见性、顺序性。
以下面代码为例:

public class StudyAVolatile {
    final static int MAX = 5;
    static volatile int init_value = 0; // 这里加入volatile才能正确运行
    public static void main(String[] args) {
        new Thread(() -> {
            int localValue = init_value;
            while (localValue < MAX) {
                if (init_value != localValue) {
                    System.out.println("初始值变化为" + init_value);
                    localValue = init_value;
                }
            }
        }, "Reader").start();
        new Thread(() -> {
            int localValue = init_value;
            while (localValue < MAX) {
                System.out.println("现在修改初始值为" + (++localValue));
                init_value = localValue;
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "Updater").start();
    }
}

在main中,我们启动了两个线程,分别是Reader和Updater。后者负责更新变量init_value的值。如果我们在注释的那一行,不加入volatile,那么Reader就无法做到监测到init_value的变化,这一个线程将不会输出任何内容。
使用了volatile,才让二者真正共用了“init_value”这个变量。
volatile不会使线程进入阻塞,而synchronized会使线程进入阻塞。
volatile的作用:
保证了多个线程之间,对共享变量操作的可见性。也就是一个线程修改volatile修饰的变量时,别的线程也会立即看到最新的值。


2023年3月18日补充
都是个人的思考

volatile可以在读的指令、写的指令前后加上内存屏障,及既保证了顺序性,又保证了可见性。不过我们也知道volatile其实没上锁,不能保证原子性。

上一篇 下一篇

猜你喜欢

热点阅读