所有。我运行以下代码来测试Java基本变量赋值是否为原子。
public class Test {
static int x = 1 << 16 - 1, y = -1 << 16, i = x;
static volatile boolean flag = false;
public static void main(String... args) {
ExecutorService executors = Executors.newFixedThreadPool(3);
executors.execute(() -> {
while (true) {
if (flag) {
return;
}
i = x;
}
});
executors.execute(() -> {
while (true) {
if (flag) {
return;
}
i = y;
}
});
executors.execute(() -> {
while (true) {
if (i != x && i != y && (flag = true)) {
System.out.println(i + "," + x + "," + y);
throw new RuntimeException("Not Equal!!");
}
}
});
}
它会抛出一个新的异常(跟随文本),但是当条件(i!= x&amp;&amp; i!= y)为真时我无法捕捉到实际的i,因为其他线程会修改变量i at同时。
Exception in thread "pool-1-thread-3" java.lang.RuntimeException: Not Equal!!
at common.Test.lambda$main$2(Test.java:31)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
32768,32768,-65536
有人可以提供一些有用的建议来帮助我找出实际的原因(如果(i!= x&amp;&amp; i!= y&amp;&amp;(flag = true))是真的吗?
答案 0 :(得分:0)
你看到的问题不是因为int赋值不是原子的:它是!
由于您正在从多个线程修改i
,因此应对所有读取和写入进行同步,否则线程可能会获得过时值,这就是您的情况,例如:
i = y
if (i != x && i != y && (flag = true))
i != x
并返回true
i = x
i != y
并返回true
if