简体   繁体   English

为什么Java基本变量分配不是原子的

[英]Why Java basic variable assignment is not atomic

all. 所有。 I run following code to test whether Java basic variable assignment is atomic or not. 我运行以下代码来测试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!!");
            }
        }
    });
}

It will throw a new exception(Follow text ), but i can not catch the actual i when condition (i != x && i != y) is true, because other thread will modify the variable i at same time. 它将引发一个新的异常(跟随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 32768,32768,-65536

Can someone give some useful advices to help me to find out the actual i which cause (if (i != x && i != y && (flag = true)) is true? 有人可以提供一些有用的建议来帮助我找出引起i的实际原因(如果(i!= x && i!= y &&(flag = true))为真吗?

The problem you're seeing is not because int assignment is not atomic: it is! 您看到的问题不是因为int赋值不是原子的:而是!

Since you're modifying i from multiple threads all reads and writes to it should be synchronized otherwise threads might get stale values and that's what happens in your case, example: 由于您正在从多个线程修改i ,因此所有读取和写入操作都应该同步,否则线程可能会获得过时的值,这就是您所遇到的情况,例如:

  1. assignment i = y 分配i = y
  2. this condition is evaluated: if (i != x && i != y && (flag = true)) 评估此条件: if (i != x && i != y && (flag = true))
  3. i != x is evaluated and returns true i != x被求值并返回true
  4. assignment i = x 分配i = x
  5. i != y is evaluated and returns true i != y被评估并返回true
  6. we're inside the if 我们在if里面

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

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