wait、notify和notifyAll方法
wait() 方法會使該鎖資源釋放,然后執行緒進入等待WAITING狀態,進入鎖的waitset中,然后等待其他執行緒對鎖資源呼叫notify方法或notifyAll方法進行喚醒,否則就會進入無限等待,喚醒后會繼續執行wait() 后面的代碼,
wait(long timeout) 和 wait(long timeout, int nanos) 兩個方法差不多,就是對wait方法的過期時間進行限制,如果超過該時間,就將執行緒放出來進入等待佇列繼續請求鎖資源,然后得到鎖資源后繼續從wait()方法后面執行,等待程序中執行緒的狀態為TIMED_WAITING,和wait()方法進行區分,
wait和sleep方法進行對比
wait方法首先會釋放鎖,然后進入一個WAITING(沒有timeout引數)或者TIMED_WAITING(有timeout引數)狀態,然后等待喚醒或者過期自動喚醒,重新去競爭鎖資源,
sleep方法就不會釋放鎖資源,直接將執行緒設定進入TIMED_WAITING狀態,等待時間過去繼續執行后續代碼
設計模式-保護性暫停
A ---- > B <------- C
首先會兩個執行緒需要對一個GuardObject 進行存取,首先A會等待C把東西放進去然后A將其取出,
class GuardObjectOld{
private Object value;
public synchronized Object getObject(){
while (value =https://www.cnblogs.com/duizhangz/archive/2022/05/04/= null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return value;
}
public synchronized void setObject(Object o){
this.value = o;
this.notifyAll();
}
}
首先呢兩個執行緒會對同一個GuardObject 物件進行存取,
取執行緒會呼叫getObject()方法,然后當value為慷訓進入wait方法等待存執行緒放入資源,
存執行緒呼叫setObject方法放入資源,然后進行通知waitset中的執行緒醒過來取資源,
然后可以對其進行增加超時保護
/**
* 增加超時檢驗
*/
@Slf4j
class GuardObject{
private Object value;
public synchronized Object getObject(long timeout){
long startTime = System.currentTimeMillis();
long waitTime = 0;
while (value =https://www.cnblogs.com/duizhangz/archive/2022/05/04/= null){
if (timeout - waitTime <= 0){
break;
}
try {
// 防止虛假喚醒,然后又要等好幾秒
this.wait(timeout - waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
waitTime = System.currentTimeMillis() - startTime;
}
return value;
}
public synchronized void setObject(Object o){
this.value = o;
this.notifyAll();
}
}
在上述代碼基礎上加入了超時保護,首先是記錄運行時間waitTime,剛開始為0,
如果程序中沒有被其他的執行緒喚醒,執行緒會執行wait(2000)方法等待2秒如果沒有被喚醒就直接繼續執行下面代碼,繼續回圈if陳述句判斷true跳出回圈,
如果程序中被其他的執行緒虛假喚醒了,然后執行緒就會發現資源還是空,然后會繼續回圈,等待時間就是設定的timeout時間減去已經等待的時間waittime,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469683.html
標籤:其他
上一篇:淺嘗Spring注解開發_簡單理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
