有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

为了理解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) 个答案

  1. # 1 楼答案

    您的main程序线程启动4个线程,然后打印总和。它不会等待这些线程完成它们的工作。使其工作的最小更改是:

    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);