condition.await和object.wait區(qū)別

1.object.wait()

使用方法:

線程A:

synchronized(obj){

obj.wait(); //此時當(dāng)前線程釋放obj鎖,進(jìn)入[等待狀態(tài)],等待其他線程執(zhí)行obj.notify()時才有可能執(zhí)行(有可能執(zhí)行的意思可能有多個線程執(zhí)行了wait)

A do something

}

線程C:

synchronized(obj){

obj.wait(); //此時當(dāng)前線程釋放obj鎖,進(jìn)入[等待狀態(tài)],等待其他線程執(zhí)行obj.notify()時才有可能執(zhí)行(有可能執(zhí)行的意思可能有多個線程執(zhí)行了wait)

C do something

}

線程B:

synchronized(obj){

obj.notify(); //此時當(dāng)前線程釋放obj鎖,隨機(jī)喚醒一個處于等待狀態(tài)的線程,繼續(xù)執(zhí)行wait后面的程序。

}

假設(shè)三個線程執(zhí)行順序

線程A-->線程C-->線程B //沒毛病,因?yàn)閣ait后是釋放了鎖的

所以問題來了:等待的線程中有A和C, B notify后,只會喚醒其中一個執(zhí)行(notifyAll同樣只有一個執(zhí)行);假如我們的需求是想讓A線程執(zhí)行,那么這種object的方式是無法控制的

2.所以condition來了

使用方法:注意condition是依賴ReentrantLock

ReentrantLock lock = new ReentrantLock(true);

Condition aCondition = reentrantLock.newCondition();

Condition cCondition = reentrantLock.newCondition();

線程A:

{

lock.lock();

aCondition.await(); //此時當(dāng)前線程釋放lock鎖,進(jìn)入[等待狀態(tài)],等待其他線程執(zhí)行aCondition.signal()時才有可能執(zhí)行

A do something

lock.unlock();

}

線程C:

{

lock.lock();

cCondition.await();

do something

lock.unlock();

}

線程B:

{

lock.lock();

aCondition.signal(); //此時當(dāng)前線程釋放lock鎖,隨機(jī)喚醒一個處于等待狀態(tài)等待aCondition的線程,繼續(xù)執(zhí)行await后面的程序。

//cCondition.signal(); ////此時當(dāng)前線程釋放lock鎖,隨機(jī)喚醒一個處于等待狀態(tài)等待cCondition的線程,繼續(xù)執(zhí)行await后面的程序。

lock.unlock();

}

所以通過condition與object進(jìn)行線程通信的區(qū)別已經(jīng)很明顯了,condition更加靈活。

個人理解,本質(zhì)上來講:

多線程環(huán)境的下,線程直接的互斥[執(zhí)行]依靠的應(yīng)該是鎖Lock,線程的之間的[通信]依靠的應(yīng)該是條件Condition/信號,一般情況下lock確實(shí)可以同時滿足做這兩個事情,所以在Object的方式滿足了這個一般情況,但是肯定會有復(fù)雜的場景比如剛才例子中,需要讓滿足一定條件的線程執(zhí)行,僅僅依靠鎖是不能完美解決的。所以condition實(shí)際上分離了執(zhí)行和通信。

以上僅是condition與object在應(yīng)用層面的上的區(qū)別,而背后的實(shí)現(xiàn)原理也是大有不同,以后再追加。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容