没有同步的两个线程访问的计数器的最小值

时间:2017-09-04 15:45:55

标签: java multithreading concurrency

我在接受采访时告诉我,在运行以下代码后,计数器的最小值是2.这怎么可能?

    class ThreadsConflict {
            private static int counter = 0;

            public static void main(String[] args) throws InterruptedException{
                    Thread t1 = new A();
                    Thread t2 = new A();
                    t1.start();
                    t2.start();

                    t1.join();
                    t2.join();

                    System.out.println(counter);
            }

            static class A extends Thread {
                    public void run() {
                            for(int i = 0; i < 10; i++) {
                                    counter++;
                            }
                    }
            }
    }

我可以理解为什么如果它们是交错的并且++运算符是冲突的,那么为什么它将是10但是它怎么可能在10以下呢?

1 个答案:

答案 0 :(得分:1)

这是因为在非原子操作之间发生交错,因此counter++可以在中间被中断,类似于:

int tmp = counter;
/* threads gets interrupted here */
counter = tmp + 1;

这可能导致角落情况如下:

  • 线程A读取0
  • 线程B读取0并写入1
  • 线程B读取1并写入2
  • ...
  • 线程B读取8并写入9
  • 线程A写1
  • 主题B读取1
  • 线程A读取1并写入2
  • 线程A读取2并写入3
  • ...
  • 线程A读取9并写入10
  • 线程A已完成
  • 线程B写2
  • 线程B完成

请注意,这是因为i被用作条件,因此如果您直接使用counter则完成10次迭代,那么您将保证至少有10次。