checkInterruptWhileWaiting
生活随笔
收集整理的這篇文章主要介紹了
checkInterruptWhileWaiting
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
如果當前線程被中斷,則調用transferAfterCancelledWait方法判斷后續的處理應該是拋出InterruptedException還是重新中斷。
這里需要注意的地方是,如果第一次CAS失敗了,則不能判斷當前線程是先進行了中斷還是先進行了signal方法的調用,可能是先執行了signal然后中斷,也可能是先執行了中斷,后執行了signal,當然,這兩個操作肯定是發生在CAS之前。這時需要做的就是等待當前線程的node被添加到AQS隊列后,也就是enq方法返回后,返回false告訴checkInterruptWhileWaiting方法返回REINTERRUPT(1),后續進行重新中斷。
簡單來說,該方法的返回值代表當前線程是否在park的時候被中斷喚醒,如果為true表示中斷在signal調用之前,signal還未執行,那么這個時候會根據await的語義,在await時遇到中斷需要拋出interruptedException,返回true就是告訴checkInterruptWhileWaiting返回THROW_IE(-1)。
如果返回false,否則表示signal已經執行過了,只需要重新響應中斷即可
private int checkInterruptWhileWaiting(Node node) { return Thread.interrupted() ? (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) :0; } final boolean transferAfterCancelledWait(Node node) {//使用cas修改節點狀態,如果還能修改成功,說明線程被中斷時,signal還沒有被調用。 // 這里有一個知識點,就是線程被喚醒,并不一定是在java層面執行了locksupport.unpark,也可能是調用了線程的interrupt()方法,這個方法會更新一個中斷標識,并且會喚醒處于阻塞狀態下的線程。 if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { enq(node); //如果cas成功,則把node添加到AQS隊列 return true; } //如果cas失敗,則判斷當前node是否已經在AQS隊列上,如果不在,則讓給其他線程執行 //當node被觸發了signal方法時,node就會被加到 aqs隊列上 while (!isOnSyncQueue(node))//循環檢測node是否已經成功添加到AQS隊列中。如果沒有,則通過yield, Thread.yield(); return false; }?
總結
以上是生活随笔為你收集整理的checkInterruptWhileWaiting的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 被阻塞的线程唤醒后的逻辑
- 下一篇: acquireQueued