成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

漫畫:如何證明sleep不釋放鎖,而wait釋放鎖?

網絡 通信技術
本文我們通過 synchronized 鎖定同一對象,來測試 wait 和 sleep 方法,再通過執行結果的先后順序證明:wait 方法會釋放鎖,而 sleep 方法并不會。

本文轉載自微信公眾號「Java中文社群」,作者磊哥。轉載本文請聯系Java中文社群公眾號。 

  1. public class WaitDemo { 
  2.     private static Object locker = new Object(); 
  3.  
  4.     public static void main(String[] args) throws InterruptedException { 
  5.         WaitDemo waitDemo = new WaitDemo(); 
  6.  
  7.         // 啟動新線程,防止主線程被休眠 
  8.         new Thread(() -> { 
  9.             try { 
  10.                 waitDemo.doWait(); 
  11.             } catch (InterruptedException e) { 
  12.                 e.printStackTrace(); 
  13.             } 
  14.         }).start(); 
  15.         Thread.sleep(200); // 此行本身沒有意義,是為了確保 wait() 先執行再執行 notify() 
  16.         waitDemo.doNotify(); 
  17.     } 
  18.  
  19.     /** 
  20.      * 執行 wait() 
  21.      */ 
  22.     private void doWait() throws InterruptedException { 
  23.         synchronized (locker) { 
  24.             System.out.println("wait start."); 
  25.             locker.wait(); 
  26.             System.out.println("wait end."); 
  27.         } 
  28.     } 
  29.  
  30.     /** 
  31.      * 執行 notify() 
  32.      */ 
  33.     private void doNotify() { 
  34.         synchronized (locker) { 
  35.             System.out.println("notify start."); 
  36.             locker.notify(); 
  37.             System.out.println("notify end."); 
  38.         } 
  39.     } 

以上程序的執行結果為:

  • wait start.
  • notify start.
  • notify end.
  • wait end.

代碼解析

從上述代碼可以看出,我們給 wait() 和 notify() 兩個方法上了同一把鎖(locker),但在調用完 wait() 方法之后 locker 鎖就被釋放了,所以程序才能正常執行 notify() 的代碼,因為是同一把鎖,如果不釋放鎖的話,是不會執行 notify()的代碼的,這一點也可以從打印的結果中證實(結果輸出順序),所以綜合以上情況來說 wait() 方法是釋放鎖的。

sleep 加鎖示例

  1. public class WaitDemo { 
  2.     private static Object locker = new Object(); 
  3.  
  4.     public static void main(String[] args) throws InterruptedException { 
  5.         WaitDemo waitDemo = new WaitDemo(); 
  6.         // 啟動新線程,防止主線程被休眠 
  7.         new Thread(() -> { 
  8.             synchronized (locker) { 
  9.                 try { 
  10.                     System.out.println("sleep start."); 
  11.                     Thread.sleep(1000); 
  12.                     System.out.println("sleep end."); 
  13.                 } catch (InterruptedException e) { 
  14.                     e.printStackTrace(); 
  15.                 } 
  16.             } 
  17.         }).start(); 
  18.  
  19.         Thread.sleep(200); 
  20.         waitDemo.doNotify(); 
  21.     } 
  22.  
  23.     /** 
  24.      * 執行 notify() 
  25.      */ 
  26.     private void doNotify() { 
  27.         synchronized (locker) { 
  28.             System.out.println("notify start."); 
  29.             locker.notify(); 
  30.             System.out.println("notify end."); 
  31.         } 
  32.     } 

以上程序的執行結果為:

  • sleep start.
  • sleep end.
  • notify start.
  • notify end.

代碼解析

從上述代碼可以看出 sleep(1000) 方法(行號:11)執行之后,調用 notify() 方法并沒有獲取到 locker 鎖,從上述執行結果中可以看出,而是執行完 sleep(1000) 方法之后才執行的 notify() 方法,因此可以證明調用 sleep() 方法并不會釋放鎖。

知識擴展

1.sleep 和 wait 有什么區別?

sleep 和 wait 幾乎是所有面試中必問的題,但想完全回答正確似乎沒那么簡單。

對于 sleep 和 wait 的區別,通常的回答是這樣的:

  • wait 必須搭配 synchronize 一起使用,而 sleep 不需要;
  • 進入 wait 狀態的線程能夠被 notify 和 notifyAll 線程喚醒,而 sleep 狀態的線程不能被 notify 方法喚醒;
  • wait 通常有條件地執行,線程會一直處于 wait 狀態,直到某個條件變為真,但是 sleep 僅僅讓你的線程進入睡眠狀態;
  • wait 方法會釋放對象鎖,但 sleep 方法不會。

但上面的回答顯然遺漏了一個重要的區別,在調用 wait 方法之后,線程會變為WATING 狀態,而調用 sleep 方法之后,線程會變為 TIMED_WAITING 狀態。

2.wait 能不能在 static 方法中使用?為什么?

不能,因為 wait 方法是實例方法(非 static 方法),因此不能在 static 中使用,源碼如下:

  1. public final void wait() throws InterruptedException { 
  2.     wait(0); 

3.wait/notify 可以不搭配 synchronized 使用嗎?為什么?

不行,因為不搭配 synchronized 使用的話程序會報錯,如下圖所示:

 

更深層次的原因是因為不加 synchronized 的話會造成 Lost Wake-Up Problem,喚醒丟失的問題,詳情可見:https://juejin.im/post/5e6a4d8a6fb9a07cd80f36d1

 

總結

本文我們通過 synchronized 鎖定同一對象,來測試 wait 和 sleep 方法,再通過執行結果的先后順序證明:wait 方法會釋放鎖,而 sleep 方法并不會。同時我們還講了幾個 wait 和 sleep 的常見面試問題,希望本文可以幫助到你。

原文鏈接:原文鏈接:https://mp.weixin.qq.com/s/eYijPq_PtMd93dsMDUPNLQ

 

責任編輯:武曉燕 來源: Java中文社群
相關推薦

2022-08-02 08:00:49

sleepwait釋放鎖

2021-07-02 08:51:09

Redisson分布式鎖公平鎖

2021-10-01 00:12:12

Redis分布式

2024-03-13 13:25:09

Redis分布式鎖

2021-07-03 17:45:57

分布式Redisson MultiLock

2021-07-09 06:48:31

ZooKeeperCurator源碼

2024-08-07 14:58:00

MySQL釋放鎖核心模塊

2018-10-16 08:40:56

Linux鎖住鍵盤桌面應用

2021-07-13 10:00:01

ThreadJoin方法

2014-08-14 10:38:30

SQL Server查詢

2024-09-03 08:06:30

AQS線程代碼

2024-03-07 07:37:03

AQS線程獨占鎖

2024-11-29 07:38:12

MySQL數據庫

2012-09-13 15:37:21

linux內存

2011-05-26 15:52:31

sleep()wait()

2024-09-03 15:14:42

2025-04-23 08:45:00

悲觀鎖樂觀鎖并發控制機制

2024-10-15 09:27:36

2019-11-28 16:00:06

重入鎖讀寫鎖樂觀鎖

2019-12-13 17:28:05

物聯網機器學習人工智能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久成人精品免费播放动漫 | 在线视频亚洲 | 日本午夜在线视频 | 亚欧洲精品在线视频免费观看 | 日韩免费高清视频 | 日本 欧美 国产 | 成人免费网站www网站高清 | 国产福利视频 | 亚洲视频一区二区三区 | 蜜桃av鲁一鲁一鲁一鲁 | 午夜国产在线 | 亚洲小视频在线播放 | 日韩三级免费网站 | 免费的日批视频 | 日韩国产免费 | 日韩成人在线播放 | 日韩精品一区二区三区免费观看 | 亚州春色| 国产精品久久久爽爽爽麻豆色哟哟 | 国产精品18久久久久久久 | 久久久久亚洲av毛片大全 | 欧美a∨ | 亚洲高清在线 | 国产精品久久九九 | 国产高清视频 | 九九九视频在线观看 | 国产成人综合亚洲欧美94在线 | 在线中文字幕第一页 | 一区二区三区在线看 | 中文字幕一区二区三区精彩视频 | 狠狠色综合久久婷婷 | 国产色婷婷精品综合在线播放 | 一级a性色生活片久久毛片 一级特黄a大片 | 午夜影院在线观看视频 | 波多野结衣电影一区 | 日韩av三区 | 日韩精品激情 | 成人亚洲网| 久久免费视频在线 | 狠狠热视频 | av电影一区 |