【意譯】Python3中的線程,GIL,線程安全(下)
655
2025-03-31
要想實(shí)現(xiàn)多個(gè)線程之間的協(xié)同,如:線程執(zhí)行先后順序、獲取某個(gè)線程執(zhí)行的結(jié)果等等。
涉及到線程之間相互通信,分為下面四類:
1 文件共享
2 網(wǎng)絡(luò)共享
socket編程問題,非本文重點(diǎn),不再贅述
3 共享變量
4 線程協(xié)作 - JDK API
細(xì)分為:
suspend/resume
、 wait/notify、 park/unpark
JDK中對(duì)于需要多線程協(xié)作完成某一任務(wù)的場(chǎng)景,提供了對(duì)應(yīng)API支持。
多線程協(xié)作的典型場(chǎng)景是:生產(chǎn)者-消費(fèi)者模型。(線程阻塞、 線程喚醒)
示例:線程1去買包子,沒有包子,則不再執(zhí)行。線程-2生產(chǎn)出包子,通知線程-1繼續(xù)執(zhí)行。
4.1 API - 被棄用的suspend和resume
作用:調(diào)用suspend掛起目標(biāo)線程,通過resume可以恢復(fù)線程執(zhí)行
被棄用的主要原因是,容易寫出
死鎖代碼
同步代碼中使用
先后順序:suspend比resume后執(zhí)行
所以用wait/notify和park/unpark機(jī)制對(duì)它進(jìn)行替代
4.2 wait/notify
這些方法只能由同一對(duì)象鎖的持有者線程調(diào)用,也就是寫在同步塊里面,否則會(huì)拋IllegalMonitorStateException
wait 方法導(dǎo)致當(dāng)前線程等待,加入該對(duì)象的等待集合中,并且放棄當(dāng)前持有的對(duì)象鎖
notify/notifyAll 方法喚醒一個(gè) 或所有正在等待這個(gè)對(duì)象鎖的線程。
雖然wait會(huì)自動(dòng)解鎖,但是對(duì)順序有要求,如果在notify被調(diào)用之后, 才開始wait方法的調(diào)用,線程會(huì)永遠(yuǎn)處于WAITING狀態(tài)。
正常使用
死鎖
小結(jié)
4.3 park/unpark
線程調(diào)用park則等待“許可”,unpark方法為指定線程提供“許可(permit)” 。
不要求park和unpark方法的調(diào)用順序
多次調(diào)用unpark之后,再調(diào)用park, 線程會(huì)直接運(yùn)行。
但不會(huì)疊加,即連續(xù)多次調(diào)用park方法,第一次會(huì)拿到“許可”直接運(yùn)行,后續(xù)調(diào)
用會(huì)進(jìn)入等待。
正常
死鎖
5 偽喚醒
** 之前代碼中用if語句來判斷,是否進(jìn)入等待狀態(tài),是錯(cuò)誤的!**
官方建議應(yīng)該在循環(huán)中檢查等待條件,原因是處于等待狀態(tài)的線程可能會(huì)收到錯(cuò)誤警報(bào)和偽
喚醒,如果不在循環(huán)中檢查等待條件,程序就會(huì)在沒有滿足結(jié)束條件的情況下退出。
偽喚醒是指線程并非因?yàn)閚otify、notifyall、 unpark等 api調(diào)用而喚醒,是更底層原因?qū)е碌摹?/p>
6 總結(jié)
涉及很多JDK多線程開發(fā)工具類及其底層實(shí)現(xiàn)的原理。
Java 任務(wù)調(diào)度
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。