2013-05-18 54 views
3

我瞭解線程是如何工作的一個問題:線程是如何工作的

class ThreadTest implements Runnable{ 
    synchronized void methodA(long n){ 
     for (int i=1;i<3;i++){System.out.print(n+" "+i)} 
    } 

    public void run(){ 
     methodA(Thread.currentThread.getId()); 
    } 

    public static void main(String ... args){ 
     new Thread(new ThreadTest()).start(); 
     new Thread(new ThreadTest()).start(); 
    } 
} 

正如我現在明白了,因爲methodA是一個for循環在這個方法進行同步,就必須下一個線程之前完成調用此方法 - 這樣結果必須如4-1 4-2 5-1 5-2...

是否有可能得到類似4-1 5-1 5-2 4-2的結果?如果是,如何?

回答

13

有沒有可能像4-1 5-1 5-2 4-2一樣的結果?

這是可能的。

如果是的話如何?

您正在使用this參考作爲由​​鎖定的對象。由於您有兩個不同的ThreadTest實例,因此每種方法都會鎖定其自己的實例,並且不會實現互斥。

所以,你必須瞭解是​​語義:總有其顯示器收購參與一個明確的對象。基本上,該對象記錄了哪個線程已經獲得了它的監視器並且將只允許相同的線程重新獲取它;其他線程將被暫停,直到顯示器被釋放。當然,任何其他對象都與此無關,它的監視器可以被任何線程自由獲取。

A​​方法隱式使用this作爲鎖。您可以爲您的示例執行的操作是在您的方法中聲明static final Object lock = new Object();並使用synchronized(lock)

+0

「每個方法都鎖定自己的實例」 - \ * facepalm \ *我怎麼忽略這個? –

+0

@JanDvorak它發生在我身上的其他場合:)這不是很難錯過它。 –

1

你可以有結果4-1 5-1 5-2 4-2。因爲你不能保證哪個線程將運行,所以你可能會得到5-1 5-2 4-1 4-2。線程開始只會將該線程放入可運行列表中。線程調度程序將決定運行哪個線程