最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java程序并發(fā)的Wait-Notify機制

 更新時間:2015年07月30日 10:55:02   作者:低調小一  
這篇文章主要介紹了詳解Java程序并發(fā)的Wait-Notify機制,多線程并發(fā)是Java編程中的重要部分,需要的朋友可以參考下

Wait-Notify場景
典型的Wait-Notify場景一般與以下兩個內容相關:
1. 狀態(tài)變量(State Variable)
當線程需要wait的時候,總是因為一些條件得不到滿足導致的。例如往隊列里填充數據,當隊列元素已經滿時,線程就需要wait停止運行。當隊列元素有空缺時,再繼續(xù)自己的執(zhí)行。
2. 條件斷言(Condition Predicate)
當線程確定是否進入wait或者是從notify醒來的時候是否繼續(xù)往下執(zhí)行,大部分都要測試狀態(tài)條件是否滿足。例如,往隊列里添加元素,隊列已滿,于是阻塞當前線程,當有其他線程從隊列里取走了元素,就通知在等待的線程“隊列有剩余空間,可以往里添加元素了”。這時,等待添加元素的進程就會被喚醒,然后判斷一下當前隊列是否真的有剩余空間,如果真的有剩余空間,就將元素添加進去,如果沒有,則繼續(xù)阻塞等待下次喚醒。
3. 條件隊列(Condition Queue)
每個對象都有一個內置的條件隊列,當一個線程在該對象鎖上調用wait函數的時候,就會將該線程加入到該對象的條件隊列中。

注意
wait與notify是Java同步機制中的重要組成部分。結合與synchronized關鍵字使用,可以建立很多優(yōu)秀的同步模型,例如生產者-消費者模型。但是在使用wait()、notify()、notifyAll()函數的時候,需要特別注意以下幾點:

    wait()、notify()、notifyAll()方法不屬于Thread類,而是屬于Object基礎類,也就是說每個對象都有wait()、notify()、notifyAll()的功能。因為每個對象都有鎖,鎖是每個對象的基礎,因此操作鎖的方法也是最基礎的。
    調用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj){...} 代碼段內。
    調用obj.wait()后,線程A就釋放了obj的鎖,否則線程B無法獲得obj鎖,也就無法在synchronized(obj){...} 代碼段內喚醒線程A。
    當obj.wait()方法返回后,線程A需要再次獲得obj鎖,才能繼續(xù)執(zhí)行。
    如果線程A1,A2,A3都在obj.wait(),則線程B調用obj.notify()只能喚醒線程A1,A2,A3中的一個(具體哪一個由JVM決定)。
    如果線程B調用obj.notifyAll()則能全部喚醒等待的線程A1,A2,A3,但是等待的線程要繼續(xù)執(zhí)行obj.wait()的下一條語句,必須獲得obj鎖。因此,線程A1,A2,A3只有一個有機會獲得鎖繼續(xù)執(zhí)行,例如A1,其余的需要等待A1釋放obj鎖之后才能繼續(xù)執(zhí)行。
    當線程B調用obj.notify()或者obj.notifyAll()的時候,線程B正持有obj鎖,因此,線程A1,A2,A3雖被喚醒,但是仍無法獲得obj鎖。直到線程B退出synchronized代碼塊,釋放obj鎖后,線程A1,A2,A3中的一個才有機會獲得對象鎖并得以繼續(xù)執(zhí)行。


示例代碼
線程的wait操作的典型代碼結構如下:

  public void test() throws InterruptedException { 
    synchronized(obj) { 
      while (! contidition) { 
        obj.wait(); 
      } 
    } 
  } 

為什么obj.wait()操作必須位于循環(huán)中呢?有以下幾個主要原因:
1. 一個對象鎖可能用于保護多個狀態(tài)變量,當它們都需要wait-notify操作時,如果不將wait放到while循環(huán)中就會有問題。例如,某對象鎖obj保護兩種狀態(tài)變量a和b,當a的條件斷言不成立時發(fā)生了wait操作,當b的條件斷言不成立時也發(fā)生了wait操作,兩個線程被加入到obj對應的條件隊列中?,F(xiàn)在若改變狀態(tài)變量a的某操作發(fā)生,在obj上調用了notifyAll操作,則obj對應的條件隊列里的所有線程均被喚醒,之前等待a的一個或幾個線程去判斷a的條件斷言可能成立了,但是b對于的條件斷言肯定仍不成立,而此時等待b的線程也被喚醒了,所以需要循環(huán)判斷b的條件斷言是否滿足,如果不滿足,則繼續(xù)wait。
2. 多個線程wait的同一狀態(tài)的條件斷言。例如,向隊列添加元素的場景,當前隊列是滿的,多個線程想往里面添加元素,于是都wait了。此時,另一個線程從隊列里取出了一個元素,調用了notifyAll操作,喚醒了所有線程,但是只有一個線程能夠往隊列里添加一個元素,其他的仍需要等待。
3. 虛假喚醒。在沒有被通知、中斷或超時的情況下,線程自動蘇醒了。雖然這種情況在實踐中很少發(fā)生,但是通過循環(huán)等待可以杜絕這一情況的發(fā)生。


相關文章

  • Java數據結構與算法之插值查找解析

    Java數據結構與算法之插值查找解析

    這篇文章主要介紹了Java數據結構與算法之插值查找解析,插值查找算法類似于二分查找,不同的就是插值查找每次從自適應mid處開始查找,需要的朋友可以參考下
    2023-12-12
  • Java抽象類原理與用法實例詳解

    Java抽象類原理與用法實例詳解

    這篇文章主要介紹了Java抽象類原理與用法,結合實例形式詳細分析了Java抽象類相關概念、原理、定義、使用方法及操作注意事項,需要的朋友可以參考下
    2019-11-11
  • Mybatis通過數據庫表自動生成實體類和xml映射文件

    Mybatis通過數據庫表自動生成實體類和xml映射文件

    這篇文章主要介紹了Mybatis通過數據庫表自動生成實體類和xml映射文件的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java 迪杰斯特拉算法實現(xiàn)查找最短距離的實現(xiàn)

    Java 迪杰斯特拉算法實現(xiàn)查找最短距離的實現(xiàn)

    這篇文章主要介紹了Java 迪杰斯特拉算法實現(xiàn)查找最短距離的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • spring?aop?pointcut?添加多個execution方式

    spring?aop?pointcut?添加多個execution方式

    這篇文章主要介紹了spring?aop?pointcut?添加多個execution方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 淺析Jmeter多用戶token使用問題

    淺析Jmeter多用戶token使用問題

    這篇文章主要介紹了Jmeter多用戶token使用問題,通過具體的例子給大家介紹了Jmeter多用戶token使用場景接口分析,需要的朋友可以參考下
    2021-10-10
  • Mybatis以main方法形式調用dao層執(zhí)行代碼實例

    Mybatis以main方法形式調用dao層執(zhí)行代碼實例

    這篇文章主要介紹了Mybatis以main方法形式調用dao層執(zhí)行代碼實例,MyBatis 是一款優(yōu)秀的持久層框架,MyBatis 免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作,需要的朋友可以參考下
    2023-08-08
  • Intellij IDEA集成JProfiler性能分析工具

    Intellij IDEA集成JProfiler性能分析工具

    作為Java程序員,性能分析是我們必須掌握的技能之一,在性能分析中,JProfiler是一款非常強大的工具,本文就來介紹一下Intellij IDEA集成JProfiler性能分析工具,就有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • SpringBoot 中使用JSP的方法示例

    SpringBoot 中使用JSP的方法示例

    本篇文章主要介紹了SpringBoot 中使用JSP的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 更改idea的JDK版本超簡單便捷方法

    更改idea的JDK版本超簡單便捷方法

    idea很多地方都設置了jdk版本,不同模塊的jdk版本也可能不一樣,下面這篇文章主要給大家介紹了關于更改idea的JDK版本的超簡單便捷方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-11-11

最新評論

调兵山市| 吴忠市| 墨竹工卡县| 温泉县| 新蔡县| 龙口市| 外汇| 夹江县| 桃源县| 衡水市| 彰化市| 五莲县| 商都县| 陇川县| 正阳县| 武穴市| 淮滨县| 鹰潭市| 静安区| 曲阳县| 博乐市| 阿拉善左旗| 将乐县| 富锦市| 库尔勒市| 区。| 西充县| 平泉县| 湖南省| 广安市| 昔阳县| 永福县| 宜丰县| 古浪县| 伊春市| 新野县| 渭南市| 凤山市| 建湖县| 环江| 翼城县|