2013-03-04 75 views
3

我正在學習java線程(同步和鎖),但不知何故,我無法找到這兩件事之間的區別。線程實例新老java

// 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 

當我們將可運行目標傳遞給線程類時,可以解釋我有什麼不同嗎?1.同一個實例 2.不同實例

回答

2

在您的代碼中,當您傳遞兩個不同的實例(SyncExample類)時,每個實例都有自己的鎖定對象(由變量obj保存)。由於有兩個不同的鎖對象,每個線程獲取一個鎖並並行執行,導致線程A和B的交錯輸出(DefineADefineBtlyAtlyB MaybeB MaybeA)。

而您通過同一個實例時,只有SyncExample類的一個實例。結果,鎖對象只有一個實例(由變量obj保存)。因此,這個鎖對象將在兩個線程之間共享。由於這種共享,只有一個線程(比如說T1)能夠進入同步塊;另一個線程(比如T2)會等到T1存在同步塊。因此,在執行時,首先看到線程A的所有打印語句,然後是線程B的所有語句(DefineAtlyA MaybeA DefineBtlyB MaybeB)。

如果我想概括一下:當你傳遞不同的實例時,只有靜態變量會影響線程的並行執行,但是當你傳遞一個實例時,靜態和類級變量(例如obj變量在你的代碼中)會影響線程的並行執行。

+0

哇。這解釋了一切。我很困惑,一直認爲obj獲得了線程A的鎖定,事實上它恰恰相反。謝謝你的評論。 – 2013-03-05 04:29:40

+0

很高興知道它有幫助。 – Kshitij 2013-03-06 06:37:48

1

輸出應該提示您有所不同。

當您將同一個SyncExample傳遞給兩個不同的線程時,其中只有一個能夠獲取obj的鎖定並執行​​塊中的代碼。

當傳遞兩個不同的SyncExample對象時,兩個線程都可以同時執行,因爲它們在不同的對象上同步。

+0

是的,我可以從輸出得到,但我的問題是爲什麼以及如何? – 2013-03-04 07:29:41

+0

你的意思是說「爲什麼」?你讀過關於同步和'synchronized'關鍵字的任何內容嗎? – 2013-03-04 10:04:57

+0

我相信Kshitij的評論對我來說很清楚。是的,我不清楚這些問題的原因。感謝您的幫助安德魯Logvinov。 :-) – 2013-03-05 04:31:48