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

Java中notify()和notifyAll()的使用區(qū)別

 更新時(shí)間:2021年06月24日 11:50:23   作者:ConstXiong  
本文主要介紹了Java中notify()和notifyAll()的使用區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下

notify() 和 notifyAll() 有什么區(qū)別?

先解釋兩個(gè)概念。

  • 等待池:假設(shè)一個(gè)線程A調(diào)用了某個(gè)對(duì)象的wait()方法,線程A就會(huì)釋放該對(duì)象的鎖后,進(jìn)入到了該對(duì)象的等待池,等待池中的線程不會(huì)去競(jìng)爭(zhēng)該對(duì)象的鎖。
  • 鎖池:只有獲取了對(duì)象的鎖,線程才能執(zhí)行對(duì)象的 synchronized 代碼,對(duì)象的鎖每次只有一個(gè)線程可以獲得,其他線程只能在鎖池中等待

然后再來(lái)說(shuō)notify和notifyAll的區(qū)別

  • 如果線程調(diào)用了對(duì)象的 wait()方法,那么線程便會(huì)處于該對(duì)象的等待池中,等待池中的線程不會(huì)去競(jìng)爭(zhēng)該對(duì)象的鎖。
  • 當(dāng)有線程調(diào)用了對(duì)象的 notifyAll()方法(喚醒所有 wait 線程)或 notify()方法(只隨機(jī)喚醒一個(gè) wait 線程),被喚醒的的線程便會(huì)進(jìn)入該對(duì)象的鎖池中,鎖池中的線程會(huì)去競(jìng)爭(zhēng)該對(duì)象鎖。也就是說(shuō),調(diào)用了notify后只要一個(gè)線程會(huì)由等待池進(jìn)入鎖池,而notifyAll會(huì)將該對(duì)象等待池內(nèi)的所有線程移動(dòng)到鎖池中,等待鎖競(jìng)爭(zhēng)
  • 優(yōu)先級(jí)高的線程競(jìng)爭(zhēng)到對(duì)象鎖的概率大,假若某線程沒(méi)有競(jìng)爭(zhēng)到該對(duì)象鎖,它還會(huì)留在鎖池中,唯有線程再次調(diào)用 wait()方法,它才會(huì)重新回到等待池中。而競(jìng)爭(zhēng)到對(duì)象鎖的線程則繼續(xù)往下執(zhí)行,直到執(zhí)行完了 synchronized 代碼塊,它會(huì)釋放掉該對(duì)象鎖,這時(shí)鎖池中的線程會(huì)繼續(xù)競(jìng)爭(zhēng)該對(duì)象鎖。

綜上,所謂喚醒線程,另一種解釋可以說(shuō)是將線程由等待池移動(dòng)到鎖池,notifyAll調(diào)用后,會(huì)將全部線程由等待池移到鎖池,然后參與鎖的競(jìng)爭(zhēng),競(jìng)爭(zhēng)成功則繼續(xù)執(zhí)行,如果不成功則留在鎖池等待鎖被釋放后再次參與競(jìng)爭(zhēng)。而notify只會(huì)喚醒一個(gè)線程。

有了這些理論基礎(chǔ),后面的notify可能會(huì)導(dǎo)致死鎖,而notifyAll則不會(huì)的例子也就好解釋了

測(cè)試代碼

public class TestNotifyNotifyAll {
 
 private static Object obj = new Object();
 
 public static void main(String[] args) {
  
  //測(cè)試 RunnableImplA wait()        
  Thread t1 = new Thread(new RunnableImplA(obj));
  Thread t2 = new Thread(new RunnableImplA(obj));
  t1.start();
  t2.start();
  
  //RunnableImplB notify()
  Thread t3 = new Thread(new RunnableImplB(obj));
  t3.start();
  
  
//  //RunnableImplC notifyAll()
//  Thread t4 = new Thread(new RunnableImplC(obj));
//  t4.start();
 }
 
}
 
 
class RunnableImplA implements Runnable {
 
 private Object obj;
 
 public RunnableImplA(Object obj) {
  this.obj = obj;
 }
 
 public void run() {
  System.out.println("run on RunnableImplA");
  synchronized (obj) {
   System.out.println("obj to wait on RunnableImplA");
   try {
    obj.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   System.out.println("obj continue to run on RunnableImplA");
  }
 }
}
 
class RunnableImplB implements Runnable {
 
 private Object obj;
 
 public RunnableImplB(Object obj) {
  this.obj = obj;
 }
 
 public void run() {
  System.out.println("run on RunnableImplB");
  System.out.println("睡眠3秒...");
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  synchronized (obj) {
   System.out.println("notify obj on RunnableImplB");
   obj.notify();
  }
 }
}
 
class RunnableImplC implements Runnable {
 
 private Object obj;
 
 public RunnableImplC(Object obj) {
  this.obj = obj;
 }
 
 public void run() {
  System.out.println("run on RunnableImplC");
  System.out.println("睡眠3秒...");
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  synchronized (obj) {
   System.out.println("notifyAll obj on RunnableImplC");
   obj.notifyAll();
  }
 }
}

結(jié)果:僅調(diào)用一次 obj.notify(),線程 t1 或 t2 中的一個(gè)始終在等待被喚醒,程序不終止

run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplB
睡眠3秒...
notify obj on RunnableImplB
obj continue to run on RunnableImplA

把 t3 注掉,啟動(dòng) t4 線程。調(diào)用 obj.notifyAll() 方法

public class TestNotifyNotifyAll { 
 private static Object obj = new Object();
  public static void main(String[] args) {
  
  //測(cè)試 RunnableImplA wait()        
  Thread t1 = new Thread(new RunnableImplA(obj));
  Thread t2 = new Thread(new RunnableImplA(obj));
  t1.start();
  t2.start();
  
//  //RunnableImplB notify()
//  Thread t3 = new Thread(new RunnableImplB(obj));
//  t3.start();
  
  
  //RunnableImplC notifyAll()
  Thread t4 = new Thread(new RunnableImplC(obj));
  t4.start();
 } 
}

結(jié)果:t1、t2線程均可以執(zhí)行完畢

run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplA
obj to wait on RunnableImplA
run on RunnableImplC
睡眠3秒...
notifyAll obj on RunnableImplC
obj continue to run on RunnableImplA
obj continue to run on RunnableImplA

到此這篇關(guān)于Java中notify()和notifyAll()的使用區(qū)別的文章就介紹到這了,更多相關(guān)Java notify()和notifyAll()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)圖片裁切的工具類(lèi)實(shí)例

    java實(shí)現(xiàn)圖片裁切的工具類(lèi)實(shí)例

    這篇文章主要介紹了java實(shí)現(xiàn)圖片裁切的工具類(lèi)實(shí)例,涉及Java針對(duì)圖片的讀取、修改等相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • Java深入探索單例模式的應(yīng)用

    Java深入探索單例模式的應(yīng)用

    單例模式(Singleton Pattern)是 Java 中最簡(jiǎn)單的設(shè)計(jì)模式之一。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式
    2022-06-06
  • Java代碼里如何拼接SQL語(yǔ)句到mybatis的xml

    Java代碼里如何拼接SQL語(yǔ)句到mybatis的xml

    這篇文章主要介紹了Java代碼里拼接SQL語(yǔ)句到mybatis的xml操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux

    Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux

    這篇文章主要介紹了Jenkins如何實(shí)現(xiàn)自動(dòng)打包部署linux,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • java編程實(shí)現(xiàn)郵件定時(shí)發(fā)送的方法

    java編程實(shí)現(xiàn)郵件定時(shí)發(fā)送的方法

    這篇文章主要介紹了java編程實(shí)現(xiàn)郵件定時(shí)發(fā)送的方法,涉及Java基于定時(shí)器實(shí)現(xiàn)計(jì)劃任務(wù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • httpclient提交json參數(shù)的示例詳解

    httpclient提交json參數(shù)的示例詳解

    httpclient使用post提交json參數(shù),和使用表單提交區(qū)分,本文結(jié)合示例代碼講解的非常詳細(xì),補(bǔ)充介紹了HttpClient請(qǐng)求傳json參數(shù)的案例代碼,感興趣的朋友一起看看吧
    2024-02-02
  • Java中的動(dòng)態(tài)和靜態(tài)編譯實(shí)例詳解

    Java中的動(dòng)態(tài)和靜態(tài)編譯實(shí)例詳解

    這篇文章主要介紹了Java中的動(dòng)態(tài)和靜態(tài)編譯實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • java中concat()方法的使用說(shuō)明

    java中concat()方法的使用說(shuō)明

    這篇文章主要介紹了java中concat()方法的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • java判斷域名無(wú)法訪問(wèn)自行訪問(wèn)下一條

    java判斷域名無(wú)法訪問(wèn)自行訪問(wèn)下一條

    這篇文章主要為大家介紹了java實(shí)現(xiàn)判斷域名無(wú)法訪問(wèn)的時(shí)候自行訪問(wèn)下一條域名示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java使用正則表達(dá)式匹配獲取鏈接地址的方法示例

    Java使用正則表達(dá)式匹配獲取鏈接地址的方法示例

    這篇文章主要介紹了Java使用正則表達(dá)式匹配獲取鏈接地址的方法,簡(jiǎn)單分析了java正則匹配常用方法及獲取網(wǎng)址鏈接的相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08

最新評(píng)論

沁阳市| 江安县| 东丰县| 长岛县| 都江堰市| 多伦县| 西平县| 平泉县| 康定县| 醴陵市| 仪征市| 阜平县| 恩平市| 淮滨县| 漠河县| 双牌县| 泰顺县| 澄迈县| 金华市| 巴塘县| 肃北| 周至县| 赣榆县| 莫力| 仙桃市| 买车| 平山县| 邵武市| 县级市| 汉阴县| 汕头市| 息烽县| 乃东县| 九龙县| 大渡口区| 手机| 徐州市| 双峰县| 洛宁县| 泰州市| 黑山县|