当前位置: 首页 > 面试题库 >

Java易失性和副作用

颜宸
2023-03-14
问题内容

Oracle有关原子访问的文档(位于http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html)说:

“一个易失性变量建立了一个事前发生的关系…。这意味着……当线程读取一个易失性变量时,它不仅看到了对易失性的最新更改,而且还看到了导致该代码的副作用改变。”

我无法解决这个问题。我了解volatile变量是如何工作的(在Java Java
5中),但是我想知道Java如何决定对volatile变量的更改有何副作用。

所以我想我的问题是:这种保证有哪些副作用?

编辑:

因此,我了解到,如果线程A修改了一个volatile变量,然后线程B读取了该变量,则在写volatile变量之前发生的所有线程A写入都相对于线程B是“一致的”(即,缓存的值)线程A进行上述写入的变量中的一部分在线程B中无效)。如我错了请纠正我。


问题答案:

大多数多处理器缓存都具有一致性机制,因此其代价不如刷新所有缓存那么糟糕。

执行此操作之前,如果在该线程中写入了volatile的所有写入操作都将被该线程读取到volatile中看到。



 类似资料:
  • 在阅读了这个问题和这个(尤其是第二个答案)之后,我对volatile及其关于记忆障碍的语义感到非常困惑。 在上面的例子中,我们写入一个易失性变量,这会导致一个mitch,这反过来会将所有挂起的存储缓冲区/加载缓冲区刷新到主缓存,使其他缓存行无效。 然而,非易失性字段可以优化并存储在寄存器中,例如?那么,我们如何才能确保给定一个写入易失性变量之前的所有状态变化都是可见的呢?如果我们有1000件东西呢

  • 问题内容: 如果高速缓存一致性是在硬件级别实现的,为什么我们需要可变的?任何内核/处理器都应该获得最新值吗? 还是完全解决了另一个问题? 问题答案: 高速缓存一致性可以在处理器级别实现,但是,除非处理器内存模型保证顺序一致性(在大多数现代体系结构中不是这种情况),否则只有在需要时才会获得高速缓存一致性。 这就是volatile的含义:它要求JVM生成相关的机器指令,这些指令将要求处理器将其缓存与主

  • 我对下面的代码段有一个问题。结果可能有一个结果[0,1,0](这是用JCStress执行的测试)。那么这是怎么发生的呢?我认为数据写入(data=1)应该在Actor2(guard2=1)中写入到guard2之前执行。我说得对吗?我问,因为很多时候我读到挥发物周围的说明没有重新排序。此外,根据这一点:http://tutorials.jenkov.com/java-concurrency/vola

  • 问题内容: 如何使数组易失?因为正如我所了解的那样,使数组易失是不安全的吗? 问题答案: 将数组声明为volatile并 不能 对其字段进行volatile访问。您是在声明引用本身是可变的,而不是元素。 换句话说,你声明 挥发性组 的元素,而不是一个 集易挥发元素 。 解决方案是在要使用整数的情况下使用。另一种方法(但有点难看)是每次您编辑字段时都将对数组的引用重写。 您可以这样做: (就像我说的

  • 来自C/C++,我对Java中的volatile对象行为有点困惑。 null faik,volatile意味着b引用的“book对象”应该在主内存中。编译器可能在内部实现引用作为指针,因此b指针可能位于缓存中。我的理解是,volatile是对象的限定符,而不是引用/指针的限定符。 问题是:在使用方法中,本地引用不是易失性的。这个“本地”引用会不会把底层的Book对象从主存带到缓存中,实质上使对象不

  • a)为什么除了“00”之外还有其他输出? b)如何修改代码以便始终打印“00”。 对于a)我的回答是:在没有任何volatile/同步构造的情况下,编译器可以重新排序一些指令。特别是“this.initialint=val;”和“this.flag=true;”可以切换,这样就可以发生这种情况:线程都启动了,t1充电在前面。给定重新排序的指令,它首先设置flag=true。在它到达“this.in