park/unpark wait/notify 區(qū)別

park/unpark和wait/notify都是Java提供給我們的機制,讓我們能夠?qū)Ξ?dāng)前線程是否陷入阻塞進行控制。

park/unpark是LockSupport包中的功能,wait/notify是Java的Object自帶的api。

二者都提供了帶時間和不帶時間版本的api來阻塞/喚醒當(dāng)前線程。

區(qū)別

1. 是否需要持有鎖

wait/notify必須在synchronized代碼塊(持有當(dāng)前對象鎖)中調(diào)用,調(diào)用wait會釋放當(dāng)前對象的對象鎖,直到被其他線程通過notify/notifyAll喚醒.

park/unpark不需要在同步塊中調(diào)用,因此不需要持有鎖。并且park/unpark實現(xiàn)方式是最多數(shù)量為1的信號量機制,通過unpark會使得信號量恢復(fù)為1,調(diào)用park時如果當(dāng)前信號量數(shù)量大于0,就直接放行(信號量數(shù)量-1),否則才阻塞當(dāng)前線程。因為park/unpark并沒有持有鎖,因此當(dāng)線程被阻塞時也就不涉及到對象鎖釋不釋放的問題了。

不需要在同步塊中調(diào)用使得park/unpark機制對比wait/notify來說,是更靈活的一種機制。

2. 對中斷的響應(yīng)處理

當(dāng)前線程因為調(diào)用wait陷入阻塞時,如果當(dāng)前線程被中斷,此時wait阻塞會被喚醒,并拋出InterruptedException.

當(dāng)線程因為park調(diào)用陷入阻塞時,如果當(dāng)前線程被中斷,此時被park阻塞的線程會被喚醒,但不會拋出InterruptedException,調(diào)用者需要通過 Thread.isInterrupted來檢查當(dāng)前線程是否被中斷了來響應(yīng)中斷。

3. 喚醒信號丟失問題

對于wait/notify來說,如果notify發(fā)生在wait之前,這個時候就可能發(fā)生喚醒信號丟失,也就是說線程會在wait處陷入阻塞。因此wait/notify需要搭配外部狀態(tài)變量來使用,避免喚醒信號丟失問題。

對于park/unpark來說,由于實現(xiàn)方式是通過信號量機制來實現(xiàn)的。一旦通過unpark將信號量恢復(fù)了,使用park時就不會阻塞,因此喚醒信號不會丟失。

如何選擇?

對于簡單的生產(chǎn)者-消費者模型,可以直接使用wait/notify,對于比較復(fù)雜的同步模型,我們通??梢允褂脳l件變量和其他并發(fā)包下的數(shù)據(jù)結(jié)構(gòu),直接使用LockSupport的機會一般來說比較少,除非現(xiàn)有同步原語不滿足需求,我們需要更精細的控制,這個時候可能會去使用LockSupport。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容