所有。我运行以下代码来测试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!!");
            }
        }
    });
}


它将抛出一个新的异常(跟随text),但是当条件(i!= x && i!= y)为true时,我无法捕获实际的i,因为其他线程会同时修改变量i。

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的实际原因(如果(i!= x && i!= y &&(flag = true))为真吗?

最佳答案

您看到的问题不是因为int赋值不是原子的:而是!

由于您要从多个线程修改i,因此所有读取和写入操作都应该同步,否则线程可能会获得过时的值,这就是您所遇到的情况,例如:


作业i = y
评估此条件:if (i != x && i != y && (flag = true))
评估i != x并返回true
作业i = x
评估i != y并返回true
我们在if

10-03 00:21