问题描述
今天阅读"深入理解java虚拟机"时,P333,关于happens-before解释,有这么一段:引用
解决方案
引用线程A: readConfig(); //读取配置 init=true; 线程B: while(init){ useConfig(); //使用配置 } 由于线程A可能会发生指令重排序,所以线程B使用的配置可能尚未加载,所以使用volatile解决此问题。 比如说,在readConfig();里有N多的指令要执行指令abcdinit=true;如果abcd和init变量都没有关系,就是不存在happens-before关系的话,若果被重排,比如说可能变成abinit=true;cd此时其实c,d还没有执行 但是b线程里init=true;已经成立了。。。所以就执行 useConfig(); 了 然后会出错
解决方案二:
引用也就是说,指令只关注线程内部指令abcd和变量init是否存在happens-before关系,不会考虑对其他线程的影响可以这么认为吧,一般来说每个线程都是有一块独立的内存区域,把共享的变量存一个副本进行操作,对其他线程的顺序是不可见的,使用了volatile相当于禁止了在线程内部内存或者是寄存器操作共享数据,而是直接在共享的主存上进行,相当于每个线程能看见别的线程对主存的操作,所以就能够保证读写顺序一般指令顺序的优化都是编译器和cpu干的事情
解决方案三:
引用happens-before是因,良好同步是果。有确定结论吗?happens-before其实就是说逻辑时钟的同步,如果满足happens-before,在执行的逻辑上必然是可以满足同步的楼主可以搜一下 分布式同步的资料 时钟同步算法思想都是一样的
解决方案四:
引用"时间上顺序与先行发生原则之间基本没有太大关系,所以我们衡量并发安全问题的时候不要受时间顺序的干扰,一切必须以先行发生原则为准。"是这样的,它的意思不是说没有关系,是说在不影响happen-before的条件下,我们可以交换指令的顺序。也就是说,happen-before的原则还是要成立的,不能被破坏。比如有四条指令happen-before关系如下,a发生在b之前 c发生在d之前A - > BC -> D那么 以下的指令顺序都是正确的,因为都不违反happen-before的条件 a,b,c,d a,c,b,dc,a,b,dc,d,a,b
解决方案五:
只要不影响结果(也不可能会影响,不然是bug了),就不会违背happens-before原则。。可以在并发编程实践中有happens-before的描述。。
解决方案六:
就我的理解来说,happens-before不是原则,而是由良好同步的代码所带来的结论,不是所有的代码都会有happens-before的那几个结论,也就是说,happens-before是结论。因为命名的原因,这因果关系很容易搞混。同时,happens-before并不以时间作为衡量标准,happens-before的那几个结论才是衡量标准。不知道这样的解释你理解否,因为我之前有过同样的疑惑(http://www.iteye.com/problems/71027),但是这关系确实有些绕。