2012-12-05 4 views
4

동기화 간단한 멀티 스레딩 시험 사용. 나는 그것이 "동기화"되었다면 다른 스레드가 기다릴 것이라고 생각했다. 내가 뭘 놓치고 있니? 이 같은자바는 스레드로부터 안전하지 멀티 스레딩 동기화

0: 0 2: 0 1: 0 3: 3  

및 기타 변화 :

0: 1 2: 0 1: 2 3: 3  

그러나 실제 출력 :

public class MultithreadingCounter implements Runnable { 

    static int count = 0; 

    public static void main(String[] args) { 
     int numThreads = 4; 
     Thread[] threads = new Thread[numThreads]; 

     for (int i = 0; i < numThreads; i++) 
      threads[i] = new Thread(new MultithreadingCounter(), i + ""); 

     for (int i = 0; i < numThreads; i++) 
      threads[i].start(); 

     for (int i = 0; i < numThreads; i++) 
      try { 
       threads[i].join(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
    }   

    @Override 
    public void run() { 
     increment(); 
    } 

    public synchronized void increment(){ 
      System.out.print(Thread.currentThread().getName() + ": " + count + "\t"); 
      count++; // if I put this first or increment it directly in the print line, it works fine. 
    } 
} 

나는이 같은 것을 표시 거라 생각 했어요. 그것은

답변

7

synchronized 키워드 인스턴스 메소드에 (즉 0,1,2,3)하지 않도록하기 위해 각각의 증가를 표시한다. 두 개의 스레드가 스레드 중 하나의 동시에 개체를이 방법을 실행할 수 없습니다. 그러나 그것은 여러분의 코드가하는 것이 아닙니다. 각 스레드는 자체 인스턴스에서 메소드를 실행합니다. 동기화는 의도 한 것처럼 보이지 않습니다. 그것이 static 메쏘드라면, 그렇게 될 것입니다.

+0

아. 나는 매일 새로운 것을 배운다. 감사. – user1877411

+0

충분히 게이트를 ('synchronized'와 조합하여)이를 'static'을 싶은, 또는 그뿐만 아니라 변수'volatile' 할 것인가? –

+1

(올바른) 동기화로 충분합니다. 그것은 이미 증분이 후속 읽기들과의 '이전 - 관계'를 가지고 있다는 것을 보장한다. 그것은 모두 '휘발성 (volatile)'이 추가하는 것이다. –

1

귀하의 increment 방법은 static해야한다 :

public static synchronized void increment() { 

는 현재 각 개체는 개별 인스턴스에서 동기화되지만 count는 정적 변수이기 때문에, 당신은 Class 개체 자체에 동기화해야합니다. 키워드가 동기화 방법 전에 사용될 때

+1

나는 당신이 3000 명의 담당자를 얻게 한 사람이었습니다, 예. D – Doorknob

0

는, 그 방법이 객체 만에 대하여 한번에 하나의 스레드에 의해 수행 될 수 있음을 보장한다. 다른 객체의 스레드 안전성을 보장하지는 않습니다.

관련 문제