2017-11-26 7 views
0

Javaの同期の仕組みを理解するために、4つのスレッドを使用して配列の合計を計算する簡単なサンプルプログラムを作成しました。私はそれが非常に効率的ではないですけど、それは私がロックを使用しているため、それが動作するはずと思われる:なぜこの同期プログラムは間違った結果を返しますか?

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です。なぜですか?

+3

スレッドを「結合」しないでください。 –

答えて

3

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); 
関連する問題