2017-11-26 5 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);