2014-10-14 2 views
0

내 운영 체제에서 코드 동작과 혼동을 느끼고 있습니다. 무엇이든간에 올바른 값을 얻으려면 멀티 스레딩을위한 동기화 방법이 많이 있습니다.동기화를 사용하지 않고 내 코드가 완벽하게 작동하는 이유는 무엇입니까?

그래서 나는 항상 올바른 가치를 얻습니다. 동기화 된 방법을 사용하지 않고 ??? !!!

예를 들어 아래의 프로그램이 매우 같은 변수에 액세스 열 개 스레드가 하나하여 증가 .. 등 몇 초 .. 그 연결되어야 후 종료한다 정규 동작 코드 아래

들여다 어떤 경우에는 100000이 아닌 다른 값을가집니다. 그리고 그 루프를 멈추게 할 것입니다. 나는 20 분 넘게이 코드를 실행하고 있습니다 .. 그리고 그것은 완벽하게 작동했습니다 ..

아무도 무슨 일이 일어나는지 말해 줄 수 있습니까? : D ??

내 운영 체제는 윈도우 7 내가 일식 케플러를 사용하고 있습니다 .. ... ..이 2.4 GHZ와 .. 정규 솔로의 JVM은 .. 8 내 CPU는 듀얼 코어 아니다

public class Worker { 
    int count; 

    public static void main(String[] args) { 
     new Worker().run(); 
    } 

    public void run() { 
     do { 
      count = 0; 
      Thread thread1 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread2 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread3 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread4 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread5 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread6 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread7 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread8 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread9 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      Thread thread10 = new Thread(new Runnable() { 
       public void run() { 
        for (int i = 0; i < 10000; i++) { 
         count++; 
        } 
       } 
      }); 

      thread1.start(); 
      thread2.start(); 
      thread3.start(); 
      thread4.start(); 
      thread5.start(); 
      thread6.start(); 
      thread7.start(); 
      thread8.start(); 
      thread9.start(); 
      thread10.start(); 

      try { 
       thread1.join(); 
       thread2.join(); 
       thread3.join(); 
       thread4.join(); 
       thread5.join(); 
       thread6.join(); 
       thread7.join(); 
       thread8.join(); 
       thread9.join(); 
       thread10.join(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

      System.out.println("Count is: " + count); 
     } while (count == 100000); 
    } 
} 
+0

@wrongAnswer : 증분이 원자 단위인지 또는 변수의 최신 값에서 작동 하는지를 확인하기 위해 변수를 여러 스레드에서 증가시킵니다. –

답변

2

나는 코드를 시도했으며 시스템에서 한 번의 반복 작업이 끝나면 즉시 종료됩니다! (그래서 나는 그것이 단지 하나의 간단한 실행에 의해 정확하지 않다는 것을 증명했습니다 - 당신이 그것을 영원히 실행할 때 올바른 이벤트라는 것을 증명할 수는 없습니다).

이것은 동시성의 뒤통수가되는 특성입니다. 오류 코드를 잘못 사용하여도 실패 할 수는 없습니다.

단일 핵심 시스템이 '문제'라고 가정합니다. 스레드가 실제로 병렬로 실행되지 않고 순차적으로 실행되므로 예상 경쟁 조건이 발생하지 않습니다.

+0

그게 내가 생각하기에 문제는 .. 예상되는 경쟁 조건이 발생하지 않는다는 것 .. 단일 핵심 시스템이기 때문에 .. 고마워!! –

+2

@Waseem : 선점으로 인해 잘못 될 수있는 단일 코어 시스템에서도. 그것과 메모리 모델, JIT 컴파일 코드가 혼합되어있을 것입니다. –

+0

@ 존 쉘 (JonSkeet) 그래서 정확히 무슨 일이 일어 났습니까? 코드보다 20 분 이상 뛰었고 종료되지 않았습니다. –

5

나는 그것이 보장 에 ... 아니더라도 ... count++ 원자 운영에 JIT 컴파일입니다 귀하의 JVM 코드를 생성 한 일어나는 의심하고 수로 컴퓨터의 메모리 모델은 느슨한하지 않습니다 있다.

여전히 안전하지 않습니다. 단지 당신이 당신의 아키텍처에서 벗어나고있는 것뿐입니다.

관련 문제