我试着去了解为什么这个例子是一个正确的同步程序:
a - volatile
Thread1:
x=a
Thread2:
a=5
因为存在冲突的访问(有到写和的读出)所以在每一个顺序的一致性执行必须是之前发生之间访问关系。 假设顺序执行的一项:
1. x=a
2. a=5
1之前发生2,为什么呢?
我试着去了解为什么这个例子是一个正确的同步程序:
a - volatile
Thread1:
x=a
Thread2:
a=5
因为存在冲突的访问(有到写和的读出)所以在每一个顺序的一致性执行必须是之前发生之间访问关系。 假设顺序执行的一项:
1. x=a
2. a=5
1之前发生2,为什么呢?
否,前一性读(以同步的顺序)相同的变量的易失性写入不一定之前发生挥发性写入。
这意味着他们可以在一个“数据争”,因为他们是“相互矛盾访问了没有通过之前发生关系,有序”。 如果这是真的几乎所有的程序包含数据争:)但是,它可能是一个规范的错误。 挥发性读写不应该被认为是一个数据的比赛。 如果程序中的所有变量是挥发性的,所有执行都是平凡的顺序是一致的。 看到http://cs.oswego.edu/pipermail/concurrency-interest/2012-January/008927.html
1之前发生2,为什么呢?
我敢肯定不是100%我明白你的问题。
如果你有一个volatile变量a
,一个线程从中读取而另一个写它,这些访问的顺序可以按任意顺序。 这是一个竞争条件 。 什么是JVM和Java内存模型(JMM)保证取决于其操作首先发生。
写可能刚好和读看到更新的价值。 或者写能读以后的事情了。 因此, x
可以是任何5
或以前的值a
。
每顺序一致性执行必须是之前发生之间的关系的访问
我不知道,所以让我更具体。 随着“关系之前发生” volatile
以前所有的内存写入的手段volatile
之前,同一个变量的读变量,保证完成。 但是,这保证不以任何方式解释了两者之间的时序volatile
操作,这些操作是受竞争条件。 读者可以保证已经看到了写,但只有当读前写发生。
你可能会认为这是一个相当薄弱的保证,但在线程,其性能急剧通过使用本地CPU缓存,读取字段的值可能来自缓存的内存段,而不是中央记忆改善。 担保是至关重要的,以确保本地线程内存无效和更新,当volatile
发生读取,这样线程可以适当地共享数据。
同样,JVM和JMM保证,如果你是从读volatile
场a
,那么任何写入同一个字段读之前已经发生了 ,会被它看到-写入的值会得到妥善公布,并可见读线程。 然而,这保证不以任何方式决定排序。 这并不是说该写有读之前发生。
很抱歉,但你不能说正确的JVM将如何优化取决于JVM的“内存模式”的代码。 你必须使用Java的高级工具,用于定义你想要的东西。
如此动荡仅仅意味着将有用于变量没有“线程间高速缓存”。
如果你想有一个严格的命令,你必须使用synchronized块。
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html
挥发性和之前发生时才有用当现场的读取硬盘的一些条件。 例如:
volatile int a;
int b =0;
Thread-1:
b = 5;
a = 10;
Thread-2
c = b + a;
在这种情况下不存在之前发生,一个可以是10或0和b可以是5或0,所以作为结果C可以是0,5,10或15。如果的读意味着一些其它条件,那么之前发生,建立了实例:
int b = 0;
volatile int a = 0;
Thread-1:
b = 5
a = 10;
Thread 2:
if(a == 10){
c = b + a;
}
在这种情况下,您将确保C = 15,因为读a==10
暗示的写b = 5
的之前发生的写a = 10
编辑:更新除了顺序注意到灰色的不一致性