日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Java并發(fā)編程之二徹底理解Java的wait和Notify機(jī)制

簡(jiǎn)單介紹

  • wait方法

wait方法的作用是使當(dāng)前執(zhí)行代碼的線(xiàn)程進(jìn)行等待,它是Object類(lèi)的方法,該方法用來(lái)將當(dāng)前線(xiàn)程置入等待隊(duì)列中,并且在wait所在的代碼行處停止執(zhí)行,直到接到通知或被中斷為止。

成都創(chuàng)新互聯(lián)一直通過(guò)網(wǎng)站建設(shè)和網(wǎng)站營(yíng)銷(xiāo)幫助企業(yè)獲得更多客戶(hù)資源。 以"深度挖掘,量身打造,注重實(shí)效"的一站式服務(wù),以成都網(wǎng)站制作、成都做網(wǎng)站、移動(dòng)互聯(lián)產(chǎn)品、成都營(yíng)銷(xiāo)網(wǎng)站建設(shè)服務(wù)為核心業(yè)務(wù)。10余年網(wǎng)站制作的經(jīng)驗(yàn),使用新網(wǎng)站建設(shè)技術(shù),全新開(kāi)發(fā)出的標(biāo)準(zhǔn)網(wǎng)站,不但價(jià)格便宜而且實(shí)用、靈活,特別適合中小公司網(wǎng)站制作。網(wǎng)站管理系統(tǒng)簡(jiǎn)單易用,維護(hù)方便,您可以完全操作網(wǎng)站資料,是中小公司快速網(wǎng)站建設(shè)的選擇。

該方法只能在同步方法或同步塊中調(diào)用(即需要先獲得對(duì)象的監(jiān)視器鎖,一般來(lái)說(shuō)在 synchronized 代碼塊或者synchronized修飾的方法中使用),否則拋出異常

IllegalMonitorStateException。

在A線(xiàn)程中調(diào)用Lock對(duì)象的wait方法以后,會(huì)釋放Lock對(duì)象的監(jiān)視器鎖,同時(shí)將A線(xiàn)程放置于Lock對(duì)象的等待隊(duì)列,A線(xiàn)程進(jìn)入WAITING狀態(tài)(Thread狀態(tài)查看系列一)。

  • notify/notifyAll方法

notify/notifyAll方法的作用是喚醒執(zhí)行對(duì)象的等待列表中的一個(gè)/所有線(xiàn)程,將其喚醒繼續(xù)工作。

同樣的,notify/notifyAll方法也只能在同步方法或同步塊中調(diào)用,即在調(diào)用前,線(xiàn)程也必須獲得該對(duì)象的監(jiān)視器鎖。

在B線(xiàn)程中調(diào)用Lock對(duì)象的notify/notifyAll方法以后,Lock對(duì)象等待隊(duì)列中的A線(xiàn)程從WAITING狀態(tài)進(jìn)入BLOCKED狀態(tài),而不是直接進(jìn)入RUNNABLE狀態(tài)。只有等B線(xiàn)程釋放了Lock對(duì)象的監(jiān)視器鎖,并且A線(xiàn)程拿到以后,才進(jìn)入到RUNNABLE狀態(tài)。所以在編程中,盡量在使用了notify/notifyAll() 后立即釋放對(duì)象的監(jiān)視器鎖,以便讓其他線(xiàn)程獲得鎖進(jìn)入RUNNABLE狀態(tài)。

  • 其他注意事項(xiàng)

wait、notify/notifyAll 方法是Object的本地final方法,無(wú)法被重寫(xiě)。

notify 和wait 的順序不能錯(cuò),如果A線(xiàn)程先執(zhí)行notify方法,B線(xiàn)程再執(zhí)行wait方法,那么B線(xiàn)程是無(wú)法被喚醒的。

實(shí)例詳解

 
 
 
  1. public class WaitThread extends Thread { 
  2.  
  3.     private Object lock; 
  4.  
  5.     public WaitThread(Object lock) { 
  6.         this.lock = lock; 
  7.     } 
  8.  
  9.     @Override 
  10.     public void run() { 
  11.         synchronized (lock) { 
  12.             System.out.println("WaitThread開(kāi)始執(zhí)行run方法"); 
  13.             try { 
  14.                 System.out.println("WaitThread開(kāi)始執(zhí)行wait方法"); 
  15.                 lock.wait(); 
  16.                 System.out.println("WaitThread被喚醒"); 
  17.             } catch (InterruptedException e) { 
  18.                 e.printStackTrace(); 
  19.             } 
  20.         } 
  21.     } 
 
 
 
  1. public class NotifyThread extends Thread { 
  2.  
  3.     private Object lock; 
  4.  
  5.     public NotifyThread(Object lock) { 
  6.         this.lock = lock; 
  7.     } 
  8.  
  9.     @Override 
  10.     public void run() { 
  11.         System.out.println("NotifyThread開(kāi)始執(zhí)行run方法"); 
  12.         try { 
  13.             System.out.println("NotifyThread睡眠2秒"); 
  14.             Thread.sleep(2000); 
  15.         } catch (InterruptedException e) { 
  16.             e.printStackTrace(); 
  17.         } 
  18.         synchronized (lock) { 
  19.             System.out.println("NotifyThread開(kāi)始執(zhí)行notify方法"); 
  20.             lock.notify(); 
  21.             try { 
  22.                 System.out.println("NotifyThread執(zhí)行notify方法后繼續(xù)睡眠2秒"); 
  23.                 Thread.sleep(2000); 
  24.             } catch (InterruptedException e) { 
  25.                 e.printStackTrace(); 
  26.             } 
  27.             System.out.println("NotifyThread睡眠2秒結(jié)束,并釋放對(duì)象監(jiān)視器鎖"); 
  28.         } 
  29.     } 
 
 
 
  1. public class Main { 
  2.     public static void main(String[] args) { 
  3.  
  4.         Object lock = new Object(); 
  5.  
  6.         // 創(chuàng)建2個(gè)線(xiàn)程 
  7.         WaitThread waitThread = new WaitThread(lock); 
  8.         NotifyThread notifyThread = new NotifyThread(lock); 
  9.         // 啟動(dòng)他們 
  10.         waitThread.start(); 
  11.         notifyThread.start(); 
  12.     } 
 
 
 
  1. NotifyThread開(kāi)始執(zhí)行run方法 
  2. WaitThread開(kāi)始執(zhí)行run方法 
  3. WaitThread開(kāi)始執(zhí)行wait方法 
  4. NotifyThread睡眠2秒 
  5. NotifyThread開(kāi)始執(zhí)行notify方法 
  6. NotifyThread執(zhí)行notify方法后繼續(xù)睡眠2秒 
  7. NotifyThread睡眠2秒結(jié)束,并釋放對(duì)象監(jiān)視器鎖 
  8. WaitThread被喚醒 

WaitThread在拿到lock的監(jiān)視器鎖以后調(diào)用wait方法。

NotifyThread在啟動(dòng)以后先睡眠2秒,保證了notify方法在wait方法后面。

NotifyThread執(zhí)行notify方法后繼續(xù)睡眠2秒,這個(gè)時(shí)候NotifyThread并沒(méi)有釋放Lock的監(jiān)視器鎖,因此WaitThread處于BLOCKED狀態(tài)并沒(méi)有被真正被喚醒。

NotifyThread睡眠2秒結(jié)束,并釋放對(duì)象監(jiān)視器鎖,這個(gè)時(shí)候NotifyThread取到Lock的監(jiān)視器鎖并進(jìn)入到RUNNABLE狀態(tài)。

進(jìn)階思考

如果A線(xiàn)程獲得了多個(gè)對(duì)象的監(jiān)視器鎖,然后調(diào)用其中1個(gè)對(duì)象的wait方法,是釋放所有對(duì)象的鎖還是只釋放調(diào)用的那個(gè)對(duì)象的鎖呢?

我們一起通過(guò)一個(gè)示例來(lái)進(jìn)行一下測(cè)試。

 
 
 
  1. public class WaitThread extends Thread { 
  2.  
  3.     private Object lock; 
  4.     private Object other; 
  5.  
  6.     public WaitThread(Object lock, Object other) { 
  7.         this.lock = lock; 
  8.         this.other = other; 
  9.     } 
  10.  
  11.     @Override 
  12.     public void run() { 
  13.         synchronized (lock) { 
  14.             synchronized (other) { 
  15.                 System.out.println("WaitThread開(kāi)始執(zhí)行run方法"); 
  16.                 try { 
  17.                     System.out.println("WaitThread開(kāi)始執(zhí)行wait方法"); 
  18.                     lock.wait(); 
  19.                     System.out.println("WaitThread被喚醒"); 
  20.                 } catch (InterruptedException e) { 
  21.                     e.printStackTrace(); 
  22.                 } 
  23.             } 
  24.         } 
  25.     } 
 
 
 
  1. public class NotifyThread extends Thread { 
  2.  
  3.     private Object lock; 
  4.     private Object other; 
  5.  
  6.     public NotifyThread(Object lock, Object other) { 
  7.         this.lock = lock; 
  8.         this.other = other; 
  9.     } 
  10.  
  11.     @Override 
  12.     public void run() { 
  13.         System.out.println("NotifyThread開(kāi)始執(zhí)行run方法"); 
  14.         try { 
  15.             System.out.println("NotifyThread睡眠2秒"); 
  16.             Thread.sleep(2000); 
  17.         } catch (InterruptedException e) { 
  18.             e.printStackTrace(); 
  19.         } 
  20.         synchronized (lock) { 
  21.             System.out.println("NotifyThread獲得lock鎖"); 
  22.  
  23.             synchronized (other) { 
  24.                 System.out.println("NotifyThread獲得other鎖"); 
  25.                 System.out.println("NotifyThread開(kāi)始執(zhí)行notify方法"); 
  26.                 lock.notify(); 
  27.                 try { 
  28.                     System.out.println("NotifyThread執(zhí)行notify方法后繼續(xù)睡眠2秒"); 
  29.                     Thread.sleep(2000); 
  30.                 } catch (InterruptedException e) { 
  31.                     e.printStackTrace(); 
  32.                 } 
  33.                 System.out.println("NotifyThread睡眠2秒結(jié)束,并釋放對(duì)象監(jiān)視器鎖"); 
  34.             } 
  35.         } 
  36.     } 
 
 
 
  1. public class Main { 
  2.     public static void main(String[] args) { 
  3.  
  4.         Object lock = new Object(); 
  5.         Object other = new Object(); 
  6.  
  7.         // 創(chuàng)建2個(gè)線(xiàn)程 
  8.         WaitThread waitThread = new WaitThread(lock, other); 
  9.         NotifyThread notifyThread = new NotifyThread(lock, other); 
  10.         // 啟動(dòng)他們 
  11.         waitThread.start(); 
  12.         notifyThread.start(); 
  13.     } 
 
 
 
  1. WaitThread開(kāi)始執(zhí)行run方法 
  2. WaitThread開(kāi)始執(zhí)行wait方法 
  3. NotifyThread開(kāi)始執(zhí)行run方法 
  4. NotifyThread睡眠2秒 
  5. NotifyThread獲得lock鎖 

WaitThread線(xiàn)程拿到lock和other的對(duì)象鎖以后,執(zhí)行了lock的wait方法。NotifyThread線(xiàn)程在睡眠2秒后,僅拿到了lock鎖,說(shuō)明wait方法只釋放了被執(zhí)行對(duì)應(yīng)的鎖,這樣就造成了死鎖。

因此如果使用wait和notify機(jī)制時(shí),一定要確認(rèn)Wait線(xiàn)程和Notify線(xiàn)程獲取對(duì)象鎖的情況,盡量避免在獲取多個(gè)對(duì)象鎖的情況下使用,防止造成死鎖問(wèn)題。


分享文章:Java并發(fā)編程之二徹底理解Java的wait和Notify機(jī)制
URL鏈接:http://www.dlmjj.cn/article/djosgie.html