volatile

作者: 张某某xyz | 来源:发表于2021-08-22 23:22 被阅读0次

20210822

保证可见性、不保证原子性、防止指令重排

保证可见性

可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改后的值

public class VolatileTest {
    private static boolean b = false;

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                // 永远不会进入这个if,线程t2将b改成了true,但是线程t1看不见
                // 解决:用volatile修饰b
                if (b) break;
            }
        }, "t1").start();

        new Thread(() -> {
            MyThreadUtil.sleepSeconds(1);
            b = true;
        }, "t2").start();
    }
}

以下是进阶

为什么可以保证可见性

JMM(Java memory model)规定每个线程使用共享变量时都将该变量拷贝一份到自己的缓存(即虚拟机栈)

多个线程都缓存共享变量时,就有缓存一致性问题(即可见性问题,一个线程不可见另一个线程对共享变量的修改),JMM的解决是:

read、load、use必须连续出现
assign、store、write必须连续出现
这样当修改变量时,就会assign=>store=>write将新值刷到主存;使用时是read=>load=>use 所以用的是最新值

为什么可以防止指令重排

因为内存屏障

如果面试官还深问,就说volatile的C++源码中locked;addl...起到内存屏障作用,就是该句代码保证的可见性和防止指令重排

参考

相关文章

网友评论

      本文标题:volatile

      本文链接:https://www.haomeiwen.com/subject/uxxybltx.html