同步synchronized方法和代碼塊

來源:互聯網
上載者:User
 

Java中,等待機制與鎖機制是密切關聯的。例如:

synchronized(obj) {
    while(!condition) {
        obj.wait();
    }
    obj.doSomething();
}

當線程A獲得了obj鎖後,發現條件condition不滿足,無法繼續下一處理,於是線程A就wait()。

在另一線程B中,如果B更改了某些條件,使得線程A的condition條件滿足了,就可以喚醒線程A:

synchronized(obj) {
    condition = true;
    obj.notify();
}

需要注意的概念是:

# 調用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) {...} 程式碼片段內。

# 調用obj.wait()後,線程A就釋放了obj的鎖,否則線程B無法獲得obj鎖,也就無法在synchronized(obj) {...} 程式碼片段內喚醒A。

# 當obj.wait()方法返回後,線程A需要再次獲得obj鎖,才能繼續執行。

# 如果A1,A2,A3都在obj.wait(),則B調用obj.notify()只能喚醒A1,A2,A3中的一個(具體哪一個由JVM決定)。

# obj.notifyAll()則能全部喚醒A1,A2,A3,但是要繼續執行obj.wait()的下一條語句,必須獲得obj鎖,因此,A1,A2,A3隻有一個有機會獲得鎖繼續執行,例如A1,其餘的需要等待A1釋放obj鎖之後才能繼續執行。

# 當B調用obj.notify/notifyAll的時候,B正持有obj鎖,因此,A1,A2,A3雖被喚醒,但是仍無法獲得obj鎖。直到B退出synchronized塊,釋放obj鎖後,A1,A2,A3中的一個才有機會獲得鎖繼續執行。

 

wait(),wait(long),notify(),notifyAll()等方法是當前類的執行個體方法,
   
        wait()是使持有對象鎖的線程釋放鎖;
        wait(long)是使持有對象鎖的線程釋放鎖時間為long(毫秒)後,再次獲得鎖,wait()和wait(0)等價;
        notify()是喚醒一個正在等待該對象鎖的線程,如果等待的線程不止一個,那麼被喚醒的線程由jvm確定;
        notifyAll是喚醒所有正在等待該對象鎖的線程. 應該優先使用notifyAll()方法,因為喚醒所有線程比喚醒一個線程更容易讓jvm找到最適合被喚醒的線程.

1.有synchronized的地方不一定有wait,notify

2.有wait,notify的地方必有synchronized.這是因為wait和notify不是屬於線程類,而是每一個對象都具有的方法,而且,這兩個方法都和對象鎖有關,有鎖的地方,必有synchronized。

另外,請注意一點:如果要把notify和wait方法放在一起用的話,必須先調用notify後調用wait,因為如果調用完wait,該線程就已經不是current thread了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.