1.object.wait()
使用方法:
線程A:
synchronized(obj){
obj.wait(); //此時當前線程釋放obj鎖,進入[等待狀態],等待其他線程執行obj.notify()時才有可能執行(有可能執行的意思可能有多個線程執行了wait)
A do something
}
線程C:
synchronized(obj){
obj.wait(); //此時當前線程釋放obj鎖,進入[等待狀態],等待其他線程執行obj.notify()時才有可能執行(有可能執行的意思可能有多個線程執行了wait)
C do something
}
線程B:
synchronized(obj){
obj.notify(); //此時當前線程釋放obj鎖,隨機喚醒一個處于等待狀態的線程,繼續執行wait后面的程序。
}
假設三個線程執行順序
線程A-->線程C-->線程B //沒毛病,因為wait后是釋放了鎖的
所以問題來了:等待的線程中有A和C, B notify后,只會喚醒其中一個執行(notifyAll同樣只有一個執行);假如我們的需求是想讓A線程執行,那么這種object的方式是無法控制的
2.所以condition來了
使用方法:注意condition是依賴ReentrantLock
ReentrantLock lock = new ReentrantLock(true);
Condition aCondition = reentrantLock.newCondition();
Condition cCondition = reentrantLock.newCondition();
線程A:
{
lock.lock();
aCondition.await(); //此時當前線程釋放lock鎖,進入[等待狀態],等待其他線程執行aCondition.signal()時才有可能執行
A do something
lock.unlock();
}
線程C:
{
lock.lock();
cCondition.await();
do something
lock.unlock();
}
線程B:
{
lock.lock();
aCondition.signal(); //此時當前線程釋放lock鎖,隨機喚醒一個處于等待狀態等待aCondition的線程,繼續執行await后面的程序。
//cCondition.signal(); ////此時當前線程釋放lock鎖,隨機喚醒一個處于等待狀態等待cCondition的線程,繼續執行await后面的程序。
lock.unlock();
}
所以通過condition與object進行線程通信的區別已經很明顯了,condition更加靈活。
個人理解,本質上來講:
多線程環境的下,線程直接的互斥[執行]依靠的應該是鎖Lock,線程的之間的[通信]依靠的應該是條件Condition/信號,一般情況下lock確實可以同時滿足做這兩個事情,所以在Object的方式滿足了這個一般情況,但是肯定會有復雜的場景比如剛才例子中,需要讓滿足一定條件的線程執行,僅僅依靠鎖是不能完美解決的。所以condition實際上分離了執行和通信。
以上僅是condition與object在應用層面的上的區別,而背后的實現原理也是大有不同,以后再追加。