2016-02-24 99 views
-1

我開始閱讀Java和我在多線程主題。另外我是C程序員,所以我對C語言的線程有所瞭解。多線程鎖定和通知

我在尋找線程如何在特定對象上相互通信。

我發現這個問題Java: How can the wait() and notify() methods be called on Objects that are not threads?但我有衝突。

我知道​​關鍵字適用鎖定機制的概念。因此,如果我同步了一個對象,然後在此對象上調用wait,是否意味着該鎖將被釋放以供另一個線程訪問?正如前面鏈接的例子

+1

等待將解鎖,並把該線程在列表中等待通知 –

+1

等待/通知是最古老和多線程最低級別的API之一。它幾乎不再使用。我建議你在過去的11年中使用新增的併發API。我將從Java 8 Streams開始並向後工作。 –

回答

3

你說你很熟悉線程C.

您可以通過想象隱式的p_thread_mutex_t變量和與每個Java對象關聯的隱式變量來理解Java的行爲。

假設我們有一些對象,foo。我們使用m(foo)來表示想象中的互斥體,並讓我們使用c(foo)來表示想像的條件變量。

一個synchronized(foo) { ... }塊鎖幾乎是一樣的:

pthread_mutex_lock(m(foo)); 
... 
pthread_mutex_unlock(m(foo)); 

唯一不同的是,Java的保證是沒有辦法脫身synchronized塊的未解鎖的互斥。即使...引發異常,互斥鎖仍將被解鎖。

所以,回答你的問題:

foo.wait()調用基本上轉化爲pthread_cond_wait(c(foo), m(foo));

1

的一般規則如下:

  • 線程只能叫wait()notify()當它獲得鎖​​

  • 兩個線程不能在運行代碼​​同時阻止。其他線程必須等待獲取該鎖。

  • 如果獲取鎖的線程調用wait(),它會自動釋放鎖。當它已被notify()編輯時,它會嘗試再次自動獲取鎖定。

2

當等待()被調用,同步對象的鎖將被釋放。請參閱Oracle文檔中的以下摘錄。 「監視器」這個詞的意思是相同的「鎖定」

「 公共最終空隙等待() 拋出InterruptedException的 造成當前線程等待,直到其他線程調用notify()方法或用於notifyAll的()方法這個對象,換句話說,這個方法的行爲就好像它只是執行調用wait(0)一樣 當前線程必須擁有這個對象的監視器。在該對象的監視器上通過調用notify方法或notifyAll方法來喚醒該線程然後等待,直到它可以重新獲得監視器的所有權並恢復執行。

如在一個參數的版本,中斷和雜散喚醒是可能的,而且這種方法應該總是在一個循環中使用:

synchronized (obj) { 
    while (<condition does not hold>) 
     obj.wait(); 
    ... // Perform action appropriate to condition 
} 

此方法應該僅由一個線程是的所有者被稱爲這個對象的監視器。有關線程可以成爲監視器所有者的方式的說明,請參閱notify方法。

+0

Re,_​​the 「監視器」這個詞的含義與「鎖定」相同_:是的,現在我想它是這樣,但是當Java發明時,「監視器」應該喚起CAR Hoare的監視器https://en.wikipedia.org/ wiki/Monitor_%28synchronization%29從這個意義上說,監視器應該是一個_object_,它有一個關聯的互斥鎖和一個或多個條件變量,並且該對象的每個method_都應該在互斥鎖上同步。 –