2015-05-02 76 views
1

首先我需要清除一些基本的東西,假設我有一個同步塊或同步方法,一個線程已經進入同步部分,5個新線程嘗試訪問同步部分,它們會停止運行直到第一個線程離開同步部分?如果他們這樣做,他們會在優先隊列中等待嗎?線程同步和單例問題

第二個問題是關於顯示器,假設我有以下代碼:
synchronized(someObject){ //do some stuff someObject.wait(); } 它是正確的假設,如果一個線程運行這段代碼,而另一個線程正在等待監視器上,然後第一個線程調用wait,第二個線程將進入代碼塊(IE等待發布someObject的顯示器)?

最後一個問題是關於一個單例實現,爲了使它的線程安全,是否足以同步單例類中的實例化行,以確保它永遠不會被多次調用?如果是這樣,這是最佳做法嗎?

+0

我認爲你應該將這些問題分解爲許多問題並詳細闡述。 – manouti

回答

2

首先我需要明確一些基本的東西,假設我有一個synchronized塊或synchronized方法和一個線程已經進入了同步的一部分,5個新的線程試圖訪問同步的一部分,他們將停止運行,直到第一個線程離開同步部分?如果他們這樣做,他們會在優先隊列中等待嗎?

如果一個線程在監視器上有鎖,其他線程無法獲取同一個對象上的同一個鎖。因此,他們會阻止。一旦當前線程放棄了它的鎖定,另一個線程就可以獲得鎖定。就優先級而言,即使一個線程的優先級高於另一個線程,也無法保證優先級較高的線程在優先級較低的線程之前運行。

ReentrantLock類的構造函數提供了創建一個公平鎖或非公平鎖的可能性。在公平場景中,線程按照它們請求的順序獲取對象上的鎖定。在不公平的情況下,如果請求可以在請求隊列中插入更高的請求,則允許執行請求攔截。

第二個問題是關於顯示器,假設我有以下代碼:

synchronized(someObject){ 
     //do some stuff 
     someObject.wait(); 
} 

它是正確的假設,如果一個線程運行這段代碼,而另一個線程正在等待上監視器然後第一個線程調用wait,第二個線程將進入代碼塊(IE等待釋放someObject的監視器)?

當等待被當前線程調用時,當前線程將釋放它在對象上的所有鎖。一旦該鎖被釋放,其他線程可能會嘗試獲取同一個對象上的同一個鎖。

最後一個問題是關於一個單例實現,爲了使它線程安全,它是否足以同步單例類中的實例化行,以確保它永遠不會被調用多次?如果是這樣,這是最佳做法嗎?

請參閱this關於線程安全單例類的文章。

+0

很好的答案。您可能還會添加這樣一個事實,即有人可以使用[ReentrantLock](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html)來控制線程鎖定公平性。而不是傳統的同步關鍵字。 –

+0

感謝您的快速回答!使所有的事情都清楚明確, – Metaldream