易失性变量和其他变量 [英] Volatile variables and other variables

查看:743
本文介绍了易失性变量和其他变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是来自经典 Concurency in Practice


写入volatile变量,随后线程B
读取相同的变量,在写入volatile变量之前,
可见的所有变量的值变为可见
到B之后读取volatile变量。


我不知道我真的能理解这个说法。例如,在这个上下文中所有变量的含义是什么?这是否意味着使用 volatile 也会对非易失性变量的使用产生副作用?

在我看来,这个语句有一些细微的

任何帮助?

解决方案

您的问题的答案在< a href =http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5-320> JLS#17.4.5 :


写入易失性字段(§8.3.1.4)发生在该字段的每次后续读取之前。


所以如果在一个线程中有

  aNonVolatileVariable = 2 // w1 
aVolatileVariable = 5 // w2

p>

  someVariable = aVolatileVariable // r1 
anotherOne = aNonVolatileVariable // r2

您保证 anotherOne 将等于2,即使该变量不易变。所以是的,使用volatile还对非易失性变量的使用产生了副作用。



更详细地说,这是由于Java Memory在同一部分中的模型(JMM):线程内顺序和传递性( hb(x,y)意味着x在y之前发生):


如果x和y是同一个线程的动作,并且x按照程序顺序在y之前,则 hb(x,y)

>
[...]

如果 hb(x,y) hb(y,z) hb(x,z)


在我的示例中:




  • hb(w1,w2) hb(r1,r2)(线程内语义)



  • 并且JMM保证程序的所有执行将是顺序一致的(即看起来没有什么已被重新排序)如果它与happens-before关系正确同步。所以在这种特殊情况下,非易失性读取保证看到非易失性写入的效果。


    The following is from classical Concurency in Practice:

    When thread A writes to a volatile variable and subsequently thread B reads the same variable, the values of all variables that were visible to A prior to writing to the volatile variable, become visible to B after reading the volatile variable.

    I am not sure I can really understand this statement. For example, what is the meaning of all variables in this context? Does this mean that using volatile also has side-effects to the usage of non-volatile variables?
    It seems to me that this statement has some subtle meaning that I can not grasp.
    Any help?

    解决方案

    The answer to your question is in JLS #17.4.5:

    A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

    So if in one thread you have

    aNonVolatileVariable = 2 //w1
    aVolatileVariable = 5 //w2
    

    And subsequently in another thread:

    someVariable = aVolatileVariable //r1
    anotherOne = aNonVolatileVariable //r2
    

    You have the guarantee that anotherOne will be equal to 2, even if that variable is not volatile. So yes, using volatile also has side-effects to the usage of non-volatile variables.

    In more details, this is due to 2 other guarantees provided by the Java Memory Model (JMM) in that same section: intra thread order and transitivity (hb(x,y) means x happens before y):

    If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
    [...]
    If hb(x, y) and hb(y, z), then hb(x, z).

    In my example:

    • hb(w1, w2) and hb(r1, r2) (intra thread semantics)
    • hb(w2, r1) because of the volatile guarantee

    so you can conclude that hb(w1, r2) by transitivity.

    And the JMM guarantees that all executions of a program will be sequentially consistent (i.e. will look like nothing has been reordered) if it is correctly synchronized with happens-before relationships. So in this specific case, the non-volatile read is guaranteed to see the effect of the non-volatile write.

    这篇关于易失性变量和其他变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆