为什么这个同步程序会返回错误的结果?

时间:2017-11-26 15:16:12

标签: java synchronization

为了理解Java同步的工作原理,我编写了一个简单的示例程序,它使用四个线程计算数组的总和。我知道它不是很有效,但似乎它应该可以工作,因为我使用锁:

public class ConcurrencyTest1 {

    static Object lock = new Object();
    static volatile int sum;

    public static void main(String[] args) {
        int[] array = new int[40000];
        Arrays.fill(array, 1);

        sum = 0;

        new Thread( ()-> {
            for (int i=0;i<10000;++i)
                synchronized(lock) {
                    sum += array[i];
                }
        } ).start();

        new Thread( ()-> {
            for (int i=10000;i<20000;++i) 
                synchronized(lock) {
                    sum += array[i];
                }
        } ).start();

        new Thread( ()-> {
            for (int i=20000;i<30000;++i) 
                synchronized(lock) {
                    sum += array[i];
                }
        } ).start();

        for (int i=30000;i<40000;++i) 
            synchronized(lock) {
                sum += array[i];
            }

        System.out.println(sum);
    }

}

正确的答案是40000.但是,当我多次运行时,我经常会得到较小的数字,如37713或30000.为什么?

1 个答案:

答案 0 :(得分:3)

您的main程序线程启动4个线程,然后打印sum。它不等待这些线程完成他们的工作。使它工作的最小变化是:

Thread t1 = new Thread(()-> {
   for (int i=0;i<10000;++i)
      synchronized(lock) {
          sum += array[i];
      }
});
...
t1.start();
....

t1.join();
...
t4.join();

System.out.println(sum);