如果读写是原子的,为啥需要 volatile [重复]
Posted
技术标签:
【中文标题】如果读写是原子的,为啥需要 volatile [重复]【英文标题】:Why is volatile needed if reads and writes are atomic [duplicate]如果读写是原子的,为什么需要 volatile [重复] 【发布时间】:2020-02-05 02:32:58 【问题描述】:Oracle documentation 声明:
对于引用变量和大多数原始变量(除 long 和 double 之外的所有类型)而言,读取和写入是原子的。
现在我想知道为什么在下面的示例中需要使用 volatile 关键字来防止无限循环 - int 变量的更改应该是原子的,因此每个人都可以立即看到,不是吗?
public class HelloWorld
// This doesn't work as expected
private static int x = 0;
//Following would work: private volatile static int x = 0;
public static void main(String []args) throws Exception
Thread t1 = new Thread(() ->
try
Thread.sleep(1000);
x = 1; //Should be atomic, right?
catch (InterruptedException e)
);
System.out.println("Begin");
t1.start();
//The evaluation of the condition should also be atomic, right?
while(x == 0)
t1.join();
System.out.println("End");
【问题讨论】:
原子性不是问题——你查过 Java 中 volatile 的含义吗?例如,tutorials.jenkov.com/java-concurrency/volatile.html,尽管到处都在讨论它。 “原子”并不意味着“立即对所有人可见”。当一个线程对某些数据执行原子操作时,这意味着其他线程要么看到它已完全完成,要么他们将看到它根本没有完成。没有其他线程会看到处于操作仅完成部分状态的数据。 【参考方案1】:读写是原子的,只是线程之间不一定可见。
需要volatile
来创建happens-before 关系:没有它,一个线程中的写入和另一个线程中的读取之间的顺序无法保证。
通过标记变量volatile
,保证一个线程中的写入对所有后续读取都是可见的(直到下一次写入,obv):写入提交到主存,然后从主存读取,而不是缓存中保存的值。
【讨论】:
以上是关于如果读写是原子的,为啥需要 volatile [重复]的主要内容,如果未能解决你的问题,请参考以下文章