2011-11-09 3 views
2

나는 다음과 같은 코드가 있습니다스레딩 및 동기화 방법

public class MyThread extends Thread { 
    private int i; 
    public static int sum=0; 
    public MyThread(int k){ 
     i=k; 
    } 




    public static void main(String[] args) throws InterruptedException{ 

     Thread t=new MyThread(1); 
     Thread s=new MyThread(2); 
     Thread p=new MyThread(3); 
     t.start(); 
     s.start();  
    } 


public synchronized void doSomething(){ 
    for(int i=0; i<100000; i++){ 
     System.out.println(this.i); 
    } 

} 

    @Override 
    public void run() { 
     doSomething(); 

    } 
} 

해봐요가 동기화됩니다. 왜 출력이 무작위입니까? 동기화 된 메서드는 동기화 된 블록과 같지만 블록의 출력은 동기화되어 있고 메서드는 그렇지 않습니다.

+0

'임의'란 무엇을 의미합니까? 코드에서 3 개의 쓰레드가 실행 중이며, 각각은 프로세서 시간을 할당 받게되므로 출력은 인터리브 될 것입니다. – Nick

+0

@mary : 예제를 확인하십시오! –

답변

8

synchronized 키워드는 동일한 개체이 인터리브되지 않도록 동기화 된 메서드 호출을 에서 방지합니다. 다른 개체에서 인터리빙 메서드 호출을 방지하지 않습니다. 세 개의 다른 객체가 있으므로 세 개의 호출이 동시에 실행될 수 있습니다.

세 스레드 모두에서 공유하는 단일 개체를 동기화해야합니다.

0

synchronized 메서드에서 사용하는 잠금은 MyThread 클래스의 인스턴스와 연결됩니다. 각 스레드는 고유 한 인스턴스 MyThread을 가지므로 각 스레드는 자체 잠금에서 동기화됩니다.

public class MyThread extends Thread { 

    private static final Object sharedLock = new Object(); 

    public void doSomething() { 
     synchronized(sharedLock) { 
     for(int i=0; i<100000; i++) { 
      System.out.println(this.i); 
     } 
     } 
    } 
    ... 
} 

대안이 MyThread.classsynchronize에,하지만 난 첫 번째 방법을 선호 : 당신은 모든 스레드에 걸쳐 동기화하고 싶다면

, 당신의 라인을 따라 뭔가를 할 수 있습니다.

synchronized(this)doSomething에 사용하도록 코드를 변경하면 갑자기 그 코드가 작동한다고하는 의견이 있습니다. 나는 그렇지 않다고 확신한다. 우연히 작동했을 수도 있지만 반복적으로 안정적으로 작동하지는 않습니다.

+0

하지만 동기화 된 (this)로 변경하고 내부에 루프를 넣으면 정렬 된 결과를 얻을 수 있지만 동기화는 mythread 클래스의 인스턴스에 있습니다. – mary

+0

@mary : 업데이트 된 답변을 참조하십시오. – NPE

1

메소드의 동기화는 동일한 객체의 호출에 대해서만 유지됩니다. 두 개의 다른 오브젝트 (두 개의 스레드)를 작성 중입니다.