日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java并发编程(2)——wait和notify解析

發布時間:2025/5/22 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java并发编程(2)——wait和notify解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

? ?JAVA的進程同步是通過synchronized()來實現的,需要說明的是,JAVA的synchronized()方法類似于操作系統概念中的互斥內存塊,在JAVA中的Object類型中,都是帶有一個內存鎖的,在有線程獲取該內存鎖后,其它線程無法訪問該內存,從而實現JAVA中簡單的同步、互斥操作。明白這個原理,就能理解為什么synchronized(this)與synchronized(static XXX)的區別了,synchronized就是針對內存區塊申請內存鎖,this關鍵字代表類的一個對象,所以其內存鎖是針對相同對象的互斥操作,而static成員屬于類專有,其內存空間為該類所有成員共有,這就導致synchronized()對static成員加鎖,相當于對類加鎖,也就是在該類的所有成員間實現互斥,在同一時間只有一個線程可訪問該類的實例。如果只是簡單的想要實現在JAVA中的線程互斥,明白這些基本就已經夠了。但如果需要在線程間相互喚醒的話就需要借助Object.wait(), Object.nofity()了。


wait與notify是java同步機制中重要的組成部分。結合與synchronized關鍵字使用,可以建立很多優秀的同步模型。
?????synchronized(this){}等價與public synchronized void method(){.....}
?????同步分為類級別和對象級別,分別對應著類鎖和對象鎖
類鎖是每個類只有一個,如果static的方法被synchronized關鍵字修飾則在這個方法被執行前必須獲得類鎖;對象鎖類同。(static synchronized是類級別的,非static的synchronized和synchronized塊都是對象級別的,即作用在同一new出來的對象上)
???? 首先,調用一個Object的wait與notify/notifyAll的時候,必須保證調用代碼對該Object是同步的,也就是說必須在作用等同于synchronized(obj){......}的內部才能夠去調用obj的wait與notify/notifyAll三個方法,否則就會報錯:
???? java.lang.IllegalMonitorStateException: current thread not owner
???? 在調用wait的時候,線程自動釋放其占有的對象鎖,同時不會去申請對象鎖。當線程被喚醒的時候,它才再次獲得了去獲得對象鎖的權利。
???? 所以,notify與notifyAll沒有太多的區別,只是notify僅喚醒一個線程并允許它去獲得鎖,notifyAll是喚醒所有等待這個對象的線程并允許它們去獲得對象鎖,只要是在synchronied塊中的代碼,沒有對象鎖是寸步難行的。其實喚醒一個線程就是重新允許這個線程去獲得對象鎖并向下運行。
?????? 順便說一下notifyall,雖然是對每個wait的對象都調用一次notify,但是這個還是有順序的,每個對象都保存這一個等待對象鏈,調用的順序就是這個鏈的順序。其實啟動等待對象鏈中各個線程的也是一個線程,在具體應用的時候,需要注意一下。


應用實例:

建立三個線程,A線程打印10次A,B線程打印10次B,C線程打印10次C,要求線程同時運行,交替打印10次ABC。這個問題用Object的wait(),notify()就可以很方便的解決。


package?cn.com.thread;/***?Description:?<交替打印10次ABC>.?<br>*?<p>*?<使用說明>*?</p>*?Makedate:2014-4-12?下午2:14:19*?*?@author?gaowenming*?@version?V1.0*/ public?class?WaitAndNotifyTest?{/***?描述?:?<描述函數實現的功能>.?<br>*?<p>*?<使用方法說明>*?</p>*?*?@param?args*/public?static?void?main(String[]?args)?{final?PrintABC?printAbc?=?new?PrintABC();//?循環加載外層for?(int?i?=?0;?i?<?10;?i++)?{new?Thread(new?Runnable()?{@Overridepublic?void?run()?{try?{printAbc.printA();?//?printA}?catch?(Exception?e)?{e.printStackTrace();}}}).start();new?Thread(new?Runnable()?{@Overridepublic?void?run()?{try?{printAbc.printB();//?printB}?catch?(Exception?e)?{e.printStackTrace();}}}).start();new?Thread(new?Runnable()?{@Overridepublic?void?run()?{try?{printAbc.printC();//?printC}?catch?(Exception?e)?{e.printStackTrace();}}}).start();}}}/***?*?*?@Description:?交替打印10次ABC*?@author?gaowenming*?@date?2014-4-12?下午2:17:11*?*/ class?PrintABC?{//?定義全局變量boolean?a?=?true;boolean?b?=?false;boolean?c?=?false;public?synchronized?void?printA()?throws?Exception?{//?用while,表示一直等待while?(!a)?{this.wait();}System.out.print("A");a?=?false;b?=?true;//?執行完后喚醒其他等待的線程notifyAll();}public?synchronized?void?printB()?throws?Exception?{while?(!b)?{this.wait();}System.out.print("B");b?=?false;c?=?true;notifyAll();}public?synchronized?void?printC()?throws?Exception?{while?(!c)?{this.wait();}System.out.println("C");c?=?false;a?=?true;notifyAll();} }


運行結果:

ABC

ABC

ABC

ABC

ABC

ABC

ABC

ABC

ABC

ABC


轉載于:https://my.oschina.net/gaowm/blog/221385

總結

以上是生活随笔為你收集整理的java并发编程(2)——wait和notify解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。