当前位置: 首页 > 知识库问答 >
问题:

易变变量和其他变量

盖泽宇
2023-03-14

以下是经典的实践中的一致性:

当线程A写入一个易失性变量,随后线程B读取相同的变量时,A在写入易失性变量之前可见的所有变量的值在读取易失性变量后变得对B可见。

我不确定我真的能理解这句话。例如,在这种情况下,所有变量的含义是什么?这是否意味着使用volatile对使用非volatile变量也有副作用<在我看来,这句话有一些我无法理解的微妙含义<有什么帮助吗?

共有2个答案

司马越
2023-03-14

这意味着如果你写十个非易失性变量,写一个易失性变量,所有的非易失性变量必须设置在易失性变量之前。

如果你读了易失性变量和所有非易失性变量,你可以确保订单不会被交换。

法弘壮
2023-03-14

您的问题的答案在JLS#17.4.5中:

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

所以如果在一个线程中

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

然后在另一个线程中:

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

您可以保证另一个将等于2,即使该变量不是易变的。是的,使用volatile对非volatile变量的使用也有副作用。

更详细地说,这是由于Java内存模型(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)(线程内语义)

所以你可以通过及物性得出hb(w1,r2)的结论。

JMM保证,如果一个程序与before关系正确同步,那么它的所有执行都将是顺序一致的(也就是说,看起来什么都没有被重新排序)。因此,在这种特定情况下,非易失性读取可以确保看到非易失性写入的效果。

 类似资料:
  • 问题内容: 以下是经典文章Concurency in Practice: 当线程A写入易失性变量,随后线程B读取相同的变量时,在写入易失性变量之前A可见的所有变量的值,在读取易失性变量后B可见。 我不确定我是否真的能理解这一说法。例如,在这种情况下,所有变量的含义是什么?这是否意味着使用volatile还会对非易失性变量的使用产生副作用? 在我看来,该声明具有我无法理解的一些微妙含义。 有什么帮助

  • 我最近与一家软件公司进行了一次面试,他问了我以下问题: 你能给我描述一下在变量前面添加volatile有什么作用吗?你能给我解释一下为什么这很重要吗? 我的大部分编程知识都来自C语言,但我的工作岗位是C#(我想如果需要的话,我可以特别为这个问题添加一些信息)

  • 问题内容: 因此,我正在阅读《 实践 中的 Java并发性》 这本书,而我只能停留在这一解释上,没有一个例子,我似乎无法理解。这是报价: 当线程将数据写入易失性变量,然后线程 读取同一变量时,在写入易失性变量之前可见的所有变量的值 将在读取易失性变量后变为可见。 有人可以给我一个反例的原因,为什么“在写入易失性变量之前可见的所有变量的值在读取易失性变量之后就变得可见”? 我很困惑,为什么在读取易失

  • 问题内容: 我需要在其他班上变数。我怎样才能做到这一点? 所以我尝试在Textcl.class中使用,但是得到了。 问题答案: 您将得到空值,因为inString从未按Robert Kilar在注释中正确指出的那样进行初始化。 您可以通过使用类名来引用静态变量。 示例ClassName.variablename。就你而言 运行您的主类。当您运行inString时,将在该类的构造函数中对其进行初始化

  • 变量可以很简单地定义成可变(var)和不可变(val)的变量。这个与Java中使用的final很相似。但是不可变在Kotlin(和其它很多现代语言)中是一个很重要的概念。 一个不可变对象意味着它在实例化之后就不能再去改变它的状态了。如果你需要一个这个对象修改之后的版本,那就会再创建一个新的对象。这个让编程更加具有健壮性和预估性。在Java中,大部分的对象是可变的,那就意味着任何可以访问它这个对象的

  • 我想用Java做一个程序来比较两个三角形。比较角度的顺序无关紧要,我知道我可以用语句来做,但有没有其他更有效的方法来比较3个角度和另外3个角度,因为三角形旋转并不重要,因为完全相同?(Java语言)