<>晦涩难懂volatile和happen-be

2019-06-04  本文已影响0人  monk87

happen-before 原则令人看了之后一头雾水,感觉理解了 ,又感觉搞不懂。如下

这里重点讨论下 ,volatile变量的这个说法 : 写优先发生于后面的读。这句到底是什么意思?

// Definition: Some variables
// 变量定义
private int first = 1;
private int second = 2;
private int third = 3;
private volatile boolean hasValue = false;
// First Snippet: A sequence of write operations being executed by Thread 1
//片段 1:线程 1 顺序的写操作
first = 5;
second = 6;
third = 7;
hasValue = true;
// Second Snippet: A sequence of read operations being executed by Thread 2
//片段 2:线程 2 顺序的读操作
System.out.println("Flag is set to : " + hasValue);
System.out.println("First: " + first);  // will print 5 打印 5
System.out.println("Second: " + second); // will print 6 打印 6
System.out.println("Third: " + third);  // will print 7 打印 7

上面的几行代码,用来解释上面那句话 。 hasValue不能和他上面的任何一句重排序。 下面的打印hasvalue的 不能和 他下面的任何一句重排序。

除了上面的作用 。还有一个作用: 就是对写优先读的准确解释 : 多个线程操作volatile变量的时候,访问这个变量的线程总能读到最后一个对他写的线程的最终值。 下面的例子来说明这个问题


    public static volatile int count = 0;


    public static void main(String[] args) {
        //
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (count == 0) {
                }
                System.out.println("886");
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count = 2;
            }
        }).start();

    }

测试后会发现 ,如果count不是volatile类型的 ,第一个线程的while循环不会终止。while会一直使用他自己线程读取到的值,不会去更新,也就是说他看不到前面线程对这个变量的修改。 如果使用volatile来修饰,后面一个线程对他进行写入操作了,第一个线程在下一个while循环立刻就能读到 。死循环立刻就终止了 。
这就是这句话的含义: 对一个变量的写操作先行发生于后面对这个变量的读操作

上一篇 下一篇

猜你喜欢

热点阅读