在Java中将变量标记为volatile
可确保每个线程都能看到上次写入的值而不是某些过时值。我想知道这是如何实现的。 JVM是否发出特殊指令来刷新CPU内存或其他内容?
答案 0 :(得分:9)
根据我的理解,它总是看起来好像缓存在写入后已被刷新,并且总是看起来好像读取是在读取时从内存直接进行的。结果是,线程总是会看到来自另一个线程的写入结果(根据Java内存模型)从不是缓存值。然而,实际的实现和CPU指令会因架构而异。
如果您在多个线程中增加变量,或者检查其值并采取某些操作,则不保证正确性,因为很明显没有实际的同步。如果只有线程写入变量而其他人都在读取,那么通常只能保证正确执行。
另请注意,64位非易失性变量可以作为两个32位变量读/写,因此32位变量在写入时是原子的,但64位变量不是。可以在另一半之前写入一半 - 因此读取的值可以是旧值或新值。
这是我的书签中非常有用的页面:
答案 1 :(得分:1)
究竟发生了什么是特定于处理器的。通常存在某种形式的存储器屏障指令。刷新整个缓存显然非常昂贵 - 硬件中存在缓存一致性协议。
同样重要的是,不会在现场访问中进行某些优化。在考虑多线程时,编译器很重要,不要只考虑硬件。