要想實現多個線程之間的協同,如:線程執行前後順序、獲取某個線程執行的結果等等。涉及到線程之間相互通訊,分爲下面四類:編程
socket編程問題,非本文重點,再也不贅述api
細分爲: suspend/resume 、 wait/notify、 park/unpark網絡
JDK中對於須要多線程協做完成某一任務的場景,提供了對應API支持。多線程協做的典型場景是:生產者-消費者模型。(線程阻塞、 線程喚醒)多線程
示例:線程1去買包子,沒有包子,則再也不執行。線程-2生產出包子,通知線程-1繼續執行。socket
做用:調用suspend掛起目標線程,經過resume能夠恢復線程執行工具
被棄用的主要緣由是,容易寫出開發工具
因此用wait/notify和park/unpark機制對它進行替代線程
這些方法只能由同一對象鎖的持有者線程調用,也就是寫在同步塊裏面,不然會拋IllegalMonitorStateException3d
wait 方法致使當前線程等待,加入該對象的等待集合中,而且放棄當前持有的對象鎖code
notify/notifyAll 方法喚醒一個 或全部正在等待這個對象鎖的線程。
雖然wait會自動解鎖,可是對順序有要求,若是在notify被調用以後, 纔開始wait方法的調用,線程會永遠處於WAITING狀態。
線程調用park則等待「許可」,unpark方法爲指定線程提供「許可(permit)」 。
不要求park和unpark方法的調用順序
屢次調用unpark以後,再調用park, 線程會直接運行。但不會疊加,即連續屢次調用park方法,第一次會拿到「許可」直接運行,後續調用會進入等待。
以前代碼中用if語句來判斷,是否進入等待狀態,是錯誤的!
官方建議應該在循環中檢查等待條件
,緣由是處於等待狀態的線程可能會收到**錯誤警報和僞喚醒**,若是不在循環中檢查等待條件,程序就會在沒有知足結束條件的狀況下退出。
僞喚醒是指線程並不是由於notify、notifyall、 unpark等 api調用而喚醒,是更底層緣由致使的。
涉及不少JDK多線程開發工具類及其底層實現的原理