简体   繁体   English

Java - 易变性和可见性

[英]Java - volatile and visibility

As far as I have read, the underlying mechanism behind volatile guarantees no reordering of operations. 据我所知,volatile背后的潜在机制保证不对操作进行重新排序。 However I am struggling to see how it guarantees visibility. 但是我很难看到它如何保证可见性。

Ie thread A writes a value. 即线程A写入一个值。 Then thread B reads it from memory, not from cache (to guarantee cache consistency). 然后线程B从内存中读取它,而不是从缓存中读取它(以保证缓存一致性)。 I know CAS does precisely this, but how does a memory barrier achieve this? 我知道CAS确实如此,但是内存屏障是如何实现这一目标的呢?

Volatile "uses" hardware specific instructions to achieve it. 易失性“使用”硬件特定指令来实现它。 Here is in-depth article about JSR-133 and Memory Barriers for Compiler Writers 这是关于JSR-133和编译器编写器的内存障碍的深入文章

I know CAS does precisely this, but how does a mem barrier achieve this? 我知道CAS确实如此,但是如何实现这一目标?

Because if you look for example inside AtomicInteger , you'll see 因为如果你在AtomicInteger寻找例子,你会看到

private volatile int value;

The memory barrier is implemented by the CPU to always show the latest value. 内存屏障由CPU实现,以始终显示最新值。 This cannot be achieved without CPU support. 没有CPU支持就无法实现这一点。

It is a common misconception that access is to main memory, however this would be very slow. 一种常见的误解是访问是主内存,但这将是非常缓慢的。 Instead there is a cache coherence bus between L2 caches. 相反,L2缓存之间存在缓存一致性总线。

There is a write store buffer before the L1 cache, but the CPU makes sure the cache line is current between cores. 在L1高速缓存之前有一个写入存储缓冲区,但CPU确保高速缓存行在核心之间是当前的。

Generic memory barrier is a CPU-specific instructions, which says 'invalidate your read cache' or 'commit your write cache', or both. 通用内存屏障是特定于CPU的指令,它表示“使读取缓存无效”或“提交写入缓存”,或两者兼而有之。 On strong-ordering CPUs like x86 there 'invalidate your read cache' is a no-op, since caches are always coherent. 在像x86这样的强排序CPU上,“使读取缓存无效”是一种无操作,因为缓存始终是连贯的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM