2013-03-04 2 views
3

자바 스레드 (동기화 및 잠금)에 대해 배우고 있었지만 어떻게 든이 두 가지의 차이점을 찾을 수 없었습니다.스레드 인스턴스 새롭고 오래된 자바

// Two different instances of SyncExample 
Thread a1 = new Thread(new SyncExample(), "A"); 
Thread b1 = new Thread(new SyncExample(), "B"); 

// Same instance is passed to both the threads 
SyncExample syn = new SyncExample(); 
Thread a2 = new Thread(syn, "A"); 
Thread b2 = new Thread(syn, "B"); 

// I believe in total 4 stacks are built. 
a1.start(); 
b1.start(); 

a2.start(); 
b2.start(); 

public class SyncExample implements Runnable { 

    Object obj = new Object(); 

    @Override 
    public void run() { 

     this.myName(); 
    } 

    private void myName() { 

     synchronized (obj) { 
      System.out.print("Define" + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException ex) { 
       System.out.println(ex); 
      } 
      System.out.print("tly" + Thread.currentThread().getName()); 
     } 
     System.out.println(" Maybe" + Thread.currentThread().getName()); 
    } 
} 


public class SyncExample implements Runnable { 

    Object obj = new Object(); 

    @Override 
    public void run() { 

     this.myName(); 
    } 

    private void myName() { 

     synchronized (obj) { 
      System.out.print("Define" + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException ex) { 
       System.out.println(ex); 
      } 
      System.out.print("tly" + Thread.currentThread().getName()); 
     } 
     System.out.println(" Maybe" + Thread.currentThread().getName()); 
    } 
} 

하지만 난이

1 사용하여이 예를 실행하면 여기에 문제가 - 동일한 레퍼런스 출력은 다음과 같습니다

DefineAtlyA MaybeA 
DefineBtlyB MaybeB 

2-2 다른 인스턴스 :

DefineADefineBtlyAtlyB MaybeB 
MaybeA 

우리가 runnable 타겟을 Thread 클래스에 넘길 때 어떤 차이가 있는지 설명 할 수있다. 1. 동일한 인스턴스 2. 다른 인스턴스

답변

2

코드에서 두 개의 다른 인스턴스 (SyncExample 클래스)를 전달하면 각 인스턴스에는 자체 잠금 객체 (변수 obj이 있음)가 있습니다. 두 개의 서로 다른 잠금 객체가 있으므로 각 스레드는 잠금을 획득하여 병렬로 실행되므로 스레드 A와 B (DefineADefineBtlyAtlyB MaybeB MaybeA)의 인터리브 출력이 발생합니다.

동일한 인스턴스를 전달하면 SyncExample 클래스의 인스턴스가 하나만 있습니다. 결과적으로 잠금 객체 (변수 obj이 보유)의 인스턴스가 하나만 존재합니다. 따라서이 잠금 객체는 두 스레드간에 공유됩니다. 이 공유 때문에 하나의 스레드 (예 : T1)만이 동기화 된 블록을 입력 할 수 있습니다. 다른 스레드 (예 : T2)는 T1이 동기화 된 블록이 존재할 때까지 대기합니다. 따라서 실행시에는 스레드 A에 대한 모든 인쇄 명령문을 먼저보고 스레드 B에 대한 모든 명령문 (DefineAtlyA MaybeA DefineBtlyB MaybeB)을 참조하십시오.

다른 인스턴스를 전달할 때 정적 변수 만 스레드의 병렬 실행에 영향을 미치지 만 단일 인스턴스를 전달하면 정적 변수와 클래스 수준 변수 (예 : obj 변수 코드에서) 스레드의 병렬 실행에 영향을 미칩니다.

+0

와우. 그것은 모든 것을 설명합니다. 나는 obj가 Thread A의 자물쇠를 획득한다고 생각하고 혼란 스러웠다. 귀하의 의견에 감사드립니다. –

+0

도움이 된 것을 알면 다행입니다. – Kshitij

1

결과는 차이점을 알려줍니다.

두 개의 다른 스레드에 동일한 SyncExample을 전달하면 그 중 하나만 obj에 대한 잠금을 획득하고 synchronized 블록의 코드를 실행할 수 있습니다.

두 개의 다른 SyncExample 개체를 전달하면 두 스레드가 서로 다른 개체에서 동기화되기 때문에 두 스레드가 동시에 실행할 수 있습니다.

+0

그래, 출력에서 ​​얻을 수 있지만 내 질문은 왜, 어떻게? –

+0

"왜"라는 말이 무슨 뜻입니까? 동기화 및'synchronized' 키워드에 대해 읽은 적이 있습니까? –

+0

글쎄, 나는 Kshitij의 코멘트가 나에게 명확하게 everyhting했다 믿습니다. 예, 질문에 대한 질문에 대한 개념이 명확하지 않았습니다. Andrew Logvinov에게 도움을 주셔서 감사합니다. :-) –