1.object.wait()
使用方法:
線程A:
synchronized(obj){
obj.wait(); //此時當前線程釋放obj鎖曹洽,進入[等待狀態(tài)],等待其他線程執(zhí)行obj.notify()時才有可能執(zhí)行(有可能執(zhí)行的意思可能有多個線程執(zhí)行了wait)
A do something
}
線程C:
synchronized(obj){
obj.wait(); //此時當前線程釋放obj鎖瓶逃,進入[等待狀態(tài)],等待其他線程執(zhí)行obj.notify()時才有可能執(zhí)行(有可能執(zhí)行的意思可能有多個線程執(zhí)行了wait)
C do something
}
線程B:
synchronized(obj){
obj.notify(); //此時當前線程釋放obj鎖截歉,隨機喚醒一個處于等待狀態(tài)的線程赴肚,繼續(xù)執(zhí)行wait后面的程序稽鞭。
}
假設三個線程執(zhí)行順序
線程A-->線程C-->線程B //沒毛病鸟整,因為wait后是釋放了鎖的
所以問題來了:等待的線程中有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(); //此時當前線程釋放lock鎖弟头,進入[等待狀態(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(); //此時當前線程釋放lock鎖,隨機喚醒一個處于等待狀態(tài)等待aCondition的線程赴恨,繼續(xù)執(zhí)行await后面的程序。
//cCondition.signal(); ////此時當前線程釋放lock鎖,隨機喚醒一個處于等待狀態(tài)等待cCondition的線程混弥,繼續(xù)執(zhí)行await后面的程序。
lock.unlock();
}
所以通過condition與object進行線程通信的區(qū)別已經(jīng)很明顯了钳垮,condition更加靈活。
個人理解额港,本質(zhì)上來講:
多線程環(huán)境的下饺窿,線程直接的互斥[執(zhí)行]依靠的應該是鎖Lock,線程的之間的[通信]依靠的應該是條件Condition/信號移斩,一般情況下lock確實可以同時滿足做這兩個事情肚医,所以在Object的方式滿足了這個一般情況,但是肯定會有復雜的場景比如剛才例子中向瓷,需要讓滿足一定條件的線程執(zhí)行肠套,僅僅依靠鎖是不能完美解決的。所以condition實際上分離了執(zhí)行和通信猖任。
以上僅是condition與object在應用層面的上的區(qū)別你稚,而背后的實現(xiàn)原理也是大有不同,以后再追加朱躺。