生产者消费者_【线程通信】生产者消费者模型
????生產(chǎn)者消費者模型,是每一個學習多線程的的人都需要知道的模型;
大致情況就是:有兩個線程,一個負責生產(chǎn)產(chǎn)品,一個消費產(chǎn)品,兩者公用同一塊內(nèi)存區(qū)域,也就是產(chǎn)品放在了同一塊內(nèi)存上面,如果兩個線程沒有采用一定的措施或者采用的策略錯誤的情況下,容易出現(xiàn)一系列的問題,例如數(shù)據(jù)一致性問題,死鎖問題;
2為什么需要生產(chǎn)者消費者模型在多線程世界里,生產(chǎn)者就是生產(chǎn)數(shù)據(jù)的線程,消費者就是消費數(shù)據(jù)的線程;如果生產(chǎn)者處理速度很快,而消費者處理速度很慢,那么生產(chǎn)者就必須等待消費者處理完,才能繼續(xù)生產(chǎn)數(shù)據(jù);同樣的道理,如果消費者的處理能力大于生產(chǎn)者,那么消費者就必須等待生產(chǎn)者;為了解決這個問題于是引入了生產(chǎn)者和消費者模式。3生產(chǎn)者-消費者模型(線程阻塞,線程喚醒)????舉例:線程1去奶茶,沒有奶茶了,它就不執(zhí)行了;線程二生產(chǎn)奶茶,通知線程1繼續(xù)執(zhí)行;
下面這個例子不大好,使用了Java線程已經(jīng)拋棄的方法
打印結(jié)果如下,最開始沒奶茶,后來有了奶茶通知了掛起的線程,那個線程就得以繼續(xù)執(zhí)行
上面這個就是經(jīng)典的生產(chǎn)者-消費者模型,但是為啥這個例子當中的線程方法被棄用了呢?往下看一個例子
suspend和resume加鎖導致死鎖
打印結(jié)果
這個線程不用等了,一直都是在這里掛起了,競爭不到鎖,沒辦法通知掛起的線程繼續(xù)執(zhí)行;
如果suspend比resume慢執(zhí)行,也會導致線程永久掛起
打印結(jié)果,通知完了,那邊才開始掛起
那么Java現(xiàn)在推薦哪一種方式進行使用呢~
wait/notify機制
這個機制要求這兩個方法只能由同一對象鎖的持有者線程進行調(diào)用,也就是卸載同步代碼塊里面,否則會拋出
IllegalMonitorStateException異常;
wait方法導致當前的線程進入等待狀態(tài),加入該對象的等待集合中,并發(fā)放棄當前持有的對象鎖;
notify/notifyAll方法喚醒一個或所有正在等待這個對象鎖的線程;
注意:雖然會wait自動解鎖,但是對順序有要求,如果在notify被調(diào)用之后才開始wait方法的調(diào)用,線程會永遠處于WAITING狀態(tài)
先來一個正常的演示(打印跟前面正常的一致)
可以看到,如果是suspend/resume的話,這個程序是會導致死鎖的,可是這里采用的是wait/notify機制,會自動釋放鎖
如果notify比waiting先執(zhí)行,
那么會導致線程一直處于WAITING的狀態(tài)
說個題外話,我覺得這個就跟你的女神已經(jīng)通知你,我們不可能在一起了,然后你還一直在等待
還有另外一個機制
park/unpark機制
park表示等待一個“許可”
unpark表示授予一個"許可"
park/unpark機制有一個好處就是如果提前頒發(fā)“許可”了
也不會導致線程一直處于掛起或者是死鎖的轉(zhuǎn)態(tài)
但是它不會主動去釋放鎖
park比unpark提前執(zhí)行的例子
本樣式由135編輯器出品,不允許任何第三方編輯器抄襲使用,違者加鎖導致死鎖的例子
【總結(jié)】
suspend/resume機制
resume先執(zhí)行,suspend慢執(zhí)行;resume/suspend加鎖;都會導致死鎖
wait/notify機制
wait/notify加鎖了會自動釋放鎖,但是notify比wait先執(zhí)行依然會線程永久掛起
park/unpark機制
park/unpark不會自動釋放鎖,但是先后執(zhí)行順序不會導致線程永久掛起
【提醒】
代碼當中使用if語句來判斷是否進入等待狀態(tài),
是錯誤的
官方建議是采用while情況下,判斷是否可以將線程掛起
總結(jié)
以上是生活随笔為你收集整理的生产者消费者_【线程通信】生产者消费者模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 装饰器实现_Python装
- 下一篇: wince导航_宁可用手机导航,也不用汽