美文网首页
<>晦涩难懂volatile和happen-be

<>晦涩难懂volatile和happen-be

作者: monk87 | 来源:发表于2019-06-04 22:11 被阅读0次

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

  • 程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
  • 锁定规则:一个unLock操作先行发生于后面对同一个锁额lock操作
  • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
  • 传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
  • 线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
  • 线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
  • 线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
  • 对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

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

  • 首先一点 ,指定了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循环立刻就能读到 。死循环立刻就终止了 。
这就是这句话的含义: 对一个变量的写操作先行发生于后面对这个变量的读操作

相关文章

  • <>晦涩难懂volatile和happen-be

    happen-before 原则令人看了之后一头雾水,感觉理解了 ,又感觉搞不懂。如下 程序次序规则:一个线程内,...

  • 晦涩难懂

    昨之午后评会,同事言笑,言为前日车内之所言。言为笑矣,字为吾言,为不知,为何,言廉耻,或为颜,为无担当,遂放弃。言...

  • 晦涩难懂

    在这个自媒体、融媒体时代,短视频似乎更被人喜爱。有笑点,有猛料,足够短。反而文字深耕者变得可贵稀少。我继续让自己每...

  • Java 多线程之Volatile

    Java 多线程之Volatile 今天来讲讲Java中经常使用到的另一个比较难懂的关键字Volatile,这个关...

  • 总结

    java基础 Java中多态的理解 反射 Java序列化与反序列化 Volatile和Synchronized e...

  • 易经晦涩难懂

    文/石墨杨 最近迷上了一本关于“易经”小说。 可是才疏学浅,如果没有注解完全看不懂,及时有注解连一知半解也不行。 ...

  • Java面试

    一、基础知识 1、Java能创建volatile数组吗? 能,Java中可以创建volatile数组,不过只是一个...

  • java并发编程笔记目录

    随缘记录~~ java并行程序基础 线程安全、volatile和CAS https://www.jianshu.c...

  • 八字实例: 高级小姐-丁亥 庚戌 戊辰 庚申

    八字实例: 小姐-丁亥 庚戌 戊辰 庚申 -- 本文需要天干地址和五行基础,没有相关基础会晦涩难懂,请谅解!--h...

  • 真·简书(10day纪念版)

    开班十天了,我感觉自己的学习效率还挺高的。学了很多JAVA的基础知识,虽然很多知识都晦涩难懂,让人头疼,但是最终还...

网友评论

      本文标题:<>晦涩难懂volatile和happen-be

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