并发int读写问题

时间:2016-06-13 13:58:36

标签: java multithreading concurrency

有人可以帮我理解为什么以下程序退出? 一个线程用1和2替换i。 另一个线程正在读取i,如果i值既不是1也不是2,它将退出。 实际上下面的程序不应该退出,但它会退出打印1或2。

static volatile int i = 1;

public static void main(String[] args) {

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                i = (i == 1 ? 2 : 1);
            }
        }
    }).start();

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                if (i != 1 && i != 2) {
                    System.out.println("i=" + i);
                    System.exit(0);
                }
            }
        }
    }).start();
}

2 个答案:

答案 0 :(得分:3)

因为在if (i != 1 && i != 2)语句中有两条检查指令,它们是按顺序计算的,因此有可能在调用i != 1时,i的值为2所以它评估为false,并且在调用i != 2时,i已被切换线程切换回值1,因此它也评估为false因此,整个if (i != 1 && i != 2)评估为false,因为java中if的评估不是原子的。

答案 1 :(得分:2)

让我们假设你在if (i != 1 && i != 2)。有两个单独的行动:

  1. read i and compare to 1
  2. read i and compare to 2
  3. 由于i是易失性的,因此编译器/ VM需要从内存中拉两次。有一种情况:(1)读取2和(2)读取1。在这种情况下,您将进入System.exit