国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

聊聊ReentrantLock 中的四個坑!

開發 前端
本文介紹了 Java 中的顯式鎖 Lock 及其子類 ReentrantLock 的使用和注意事項,Lock 在 Java 中占據了鎖的半壁江山,但在使用時卻要注意四個問題。

作者 | 王磊

來源 | Java中文社群(ID:javacn666)

轉載請聯系授權(微信ID:GG_Stone)

JDK 1.5 之前 synchronized 的性能是比較低的,但在 JDK 1.5 中,官方推出一個重量級功能 Lock,一舉改變了 Java 中鎖的格局。JDK 1.5 之前當我們談到鎖時,只能使用內置鎖 synchronized,但如今我們鎖的實現又多了一種顯式鎖 Lock。

本文咱們重點來看 Lock。

Lock 簡介

Lock 是一個頂級接口,它的所有方法如下圖所示:

它的子類列表如下:

 

我們通常會使用 ReentrantLock 來定義其實例,它們之間的關聯如下圖所示:

“PS:Sync 是同步鎖的意思,FairSync 是公平鎖,NonfairSync 是非公平鎖。

ReentrantLock 使用

學習任何一項技能都是先從使用開始的,所以我們也不例外,咱們先來看下 ReentrantLock 的基礎使用:

  1. publicclass LockExample { 
  2.     // 創建鎖對象 
  3.     privatefinal ReentrantLock lock = new ReentrantLock(); 
  4.     public void method() { 
  5.         // 加鎖操作 
  6.         lock.lock(); 
  7.         try { 
  8.             // 業務代碼...... 
  9.         } finally { 
  10.             // 釋放鎖 
  11.             lock.unlock(); 
  12.         } 
  13.     } 

ReentrantLock 在創建之后,有兩個關鍵性的操作:

  • 加鎖操作:lock()
  • 釋放鎖操作:unlock()

ReentrantLock 中的坑

1.ReentrantLock 默認為非公平鎖

很多人會認為(尤其是新手朋友),ReentrantLock 默認的實現是公平鎖,其實并非如此,ReentrantLock 默認情況下為非公平鎖(這主要是出于性能方面的考慮),比如下面這段代碼:

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(); 
  6.  
  7.     public static void main(String[] args) { 
  8.         // 定義線程任務 
  9.         Runnable runnable = new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 // 加鎖 
  13.                 lock.lock(); 
  14.                 try { 
  15.                     // 打印執行線程的名字 
  16.                     System.out.println("線程:" + Thread.currentThread().getName()); 
  17.                 } finally { 
  18.                     // 釋放鎖 
  19.                     lock.unlock(); 
  20.                 } 
  21.             } 
  22.         }; 
  23.         // 創建多個線程 
  24.         for (int i = 0; i < 10; i++) { 
  25.             new Thread(runnable).start(); 
  26.         } 
  27.     } 

以上程序的執行結果如下:

從上述執行的結果可以看出,ReentrantLock 默認情況下為非公平鎖。因為線程的名稱是根據創建的先后順序遞增的,所以如果是公平鎖,那么線程的執行應該是有序遞增的,但從上述的結果可以看出,線程的執行和打印是無序的,這說明 ReentrantLock 默認情況下為非公平鎖。

想要將 ReentrantLock 設置為公平鎖也很簡單,只需要在創建 ReentrantLock 時,設置一個 true 的構造參數就可以了,如下代碼所示:

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象(公平鎖) 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(true); 
  6.  
  7.     public static void main(String[] args) { 
  8.         // 定義線程任務 
  9.         Runnable runnable = new Runnable() { 
  10.             @Override 
  11.             public void run() { 
  12.                 // 加鎖 
  13.                 lock.lock(); 
  14.                 try { 
  15.                     // 打印執行線程的名字 
  16.                     System.out.println("線程:" + Thread.currentThread().getName()); 
  17.                 } finally { 
  18.                     // 釋放鎖 
  19.                     lock.unlock(); 
  20.                 } 
  21.             } 
  22.         }; 
  23.         // 創建多個線程 
  24.         for (int i = 0; i < 10; i++) { 
  25.             new Thread(runnable).start(); 
  26.         } 
  27.     } 

以上程序的執行結果如下:

從上述結果可以看出,當我們顯式的給 ReentrantLock 設置了 true 的構造參數之后,ReentrantLock 就變成了公平鎖,線程獲取鎖的順序也變成有序的了。

其實從 ReentrantLock 的源碼我們也可以看出它究竟是公平鎖還是非公平鎖,ReentrantLock 部分源碼實現如下:

  1. public ReentrantLock() { 
  2.      sync = new NonfairSync(); 
  3.  } 
  4. public ReentrantLock(boolean fair) { 
  5.     sync = fair ? new FairSync() : new NonfairSync(); 

從上述源碼中可以看出,默認情況下 ReentrantLock 會創建一個非公平鎖,如果在創建時顯式的設置構造參數的值為 true 時,它就會創建一個公平鎖。

2.在 finally 中釋放鎖

使用 ReentrantLock 時一定要記得釋放鎖,否則就會導致該鎖一直被占用,其他使用該鎖的線程則會永久的等待下去,所以我們在使用 ReentrantLock 時,一定要在 finally 中釋放鎖,這樣就可以保證鎖一定會被釋放。

反例

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(); 
  6.     public static void main(String[] args) { 
  7.         // 加鎖操作 
  8.         lock.lock(); 
  9.         System.out.println("Hello,ReentrantLock."); 
  10.         // 此處會報異常,導致鎖不能正常釋放 
  11.         int number = 1 / 0; 
  12.         // 釋放鎖 
  13.         lock.unlock(); 
  14.         System.out.println("鎖釋放成功!"); 
  15.     } 

以上程序的執行結果如下:

從上述結果可以看出,當出現異常時鎖未被正常釋放,這樣就會導致其他使用該鎖的線程永久的處于等待狀態。

正例

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(); 
  6.     public static void main(String[] args) { 
  7.         // 加鎖操作 
  8.         lock.lock(); 
  9.         try { 
  10.             System.out.println("Hello,ReentrantLock."); 
  11.             // 此處會報異常 
  12.             int number = 1 / 0; 
  13.         } finally { 
  14.             // 釋放鎖 
  15.             lock.unlock(); 
  16.             System.out.println("鎖釋放成功!"); 
  17.         } 
  18.     } 

以上程序的執行結果如下:

從上述結果可以看出,雖然方法中出現了異常情況,但并不影響 ReentrantLock 鎖的釋放操作,這樣其他使用此鎖的線程就可以正常獲取并運行了。

3.鎖不能被釋放多次

lock 操作的次數和 unlock 操作的次數必須一一對應,且不能出現一個鎖被釋放多次的情況,因為這樣就會導致程序報錯。

反例

一次 lock 對應了兩次 unlock 操作,導致程序報錯并終止執行,示例代碼如下:

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(); 
  6.  
  7.     public static void main(String[] args) { 
  8.         // 加鎖操作 
  9.         lock.lock(); 
  10.          
  11.         // 第一次釋放鎖 
  12.         try { 
  13.             System.out.println("執行業務 1~"); 
  14.             // 業務代碼 1...... 
  15.         } finally { 
  16.             // 釋放鎖 
  17.             lock.unlock(); 
  18.             System.out.println("鎖釋鎖"); 
  19.         } 
  20.  
  21.         // 第二次釋放鎖 
  22.         try { 
  23.             System.out.println("執行業務 2~"); 
  24.             // 業務代碼 2...... 
  25.         } finally { 
  26.             // 釋放鎖 
  27.             lock.unlock(); 
  28.             System.out.println("鎖釋鎖"); 
  29.         } 
  30.         // 最后的打印操作 
  31.         System.out.println("程序執行完成."); 
  32.     } 

以上程序的執行結果如下:

從上述結果可以看出,執行第 2 個 unlock 時,程序報錯并終止執行了,導致異常之后的代碼都未正常執行。

4.lock 不要放在 try 代碼內

在使用 ReentrantLock 時,需要注意不要將加鎖操作放在 try 代碼中,這樣會導致未加鎖成功就執行了釋放鎖的操作,從而導致程序執行異常。

反例

  1. import java.util.concurrent.locks.ReentrantLock; 
  2.  
  3. publicclass LockExample { 
  4.     // 創建鎖對象 
  5.     privatestaticfinal ReentrantLock lock = new ReentrantLock(); 
  6.  
  7.     public static void main(String[] args) { 
  8.         try { 
  9.             // 此處異常 
  10.             int num = 1 / 0; 
  11.             // 加鎖操作 
  12.             lock.lock(); 
  13.         } finally { 
  14.             // 釋放鎖 
  15.             lock.unlock(); 
  16.             System.out.println("鎖釋鎖"); 
  17.         } 
  18.         System.out.println("程序執行完成."); 
  19.     } 

以上程序的執行結果如下:

從上述結果可以看出,如果將加鎖操作放在 try 代碼中,可能會導致兩個問題:

  1. 未加鎖成功就執行了釋放鎖的操作,從而導致了新的異常;
  2. 釋放鎖的異常會覆蓋程序原有的異常,從而增加了排查問題的難度。

總結

本文介紹了 Java 中的顯式鎖 Lock 及其子類 ReentrantLock 的使用和注意事項,Lock 在 Java 中占據了鎖的半壁江山,但在使用時卻要注意 4 個問題:

  1. 默認情況下 ReentrantLock 為非公平鎖而非公平鎖;
  2. 加鎖次數和釋放鎖次數一定要保持一致,否則會導致線程阻塞或程序異常;
  3. 加鎖操作一定要放在 try 代碼之前,這樣可以避免未加鎖成功又釋放鎖的異常;
  4. 釋放鎖一定要放在 finally 中,否則會導致線程阻塞。

 

責任編輯:姜華 來源: Java中文社群
相關推薦

2025-07-25 09:02:56

2021-11-05 07:59:25

HashMapJava知識總結

2022-01-12 15:50:24

JavaScript開發循環

2022-12-19 16:07:22

數據治理IT

2022-12-12 08:47:06

2022-05-04 12:44:57

Python編程語言

2020-08-13 10:29:55

項目管理項目經理CIO

2024-04-11 09:38:15

2022-03-02 08:20:54

并發編程java后端開發

2024-05-10 12:33:06

flask裝飾器

2011-07-14 15:23:34

java

2021-01-25 10:40:56

Python 開發編程語言

2022-02-23 15:09:18

數字化轉型國有企業數據

2013-03-18 13:31:28

2024-06-25 12:45:05

2010-06-29 09:06:39

Java思想Java虛擬機

2024-11-14 09:00:00

Python編程元編程

2011-05-18 09:32:14

java

2023-10-26 07:47:35

JavaScript代碼變量

2010-03-30 11:00:46

Oracle 數據
點贊
收藏

51CTO技術棧公眾號

4444欧美成人kkkk| 成人免费自拍视频| 欧美日韩国产亚洲沙发| gogo亚洲高清大胆美女人体 | 91成人国产精品| 97国产精东麻豆人妻电影| 黄色工厂这里只有精品| 国产日韩欧美视频| 亚洲宅男网av| 亚洲免费伊人电影在线观看av| 中文亚洲视频在线| 国产啊啊啊视频在线观看| 欧美色图在线视频| 春暖花开亚洲| 伊人色综合久久天天| 久久久精品麻豆| 国产亚洲欧美中文| 日本999视频| 国产欧美综合色| 手机看片福利日韩| 国产精品欧美经典| 激情视频网址| 中午字幕在线观看| 亚洲一二区在线| 麻豆精品新av中文字幕| 欧美视频1区| 蜜臀91精品一区二区三区| 欧美一区1区三区3区公司 | 欧美在线免费观看亚洲| 久久婷婷国产91天堂综合精品| 国产传媒日韩欧美成人| 亚洲天堂第一区| 国产麻豆成人传媒免费观看| 正在播放精油久久| 国产一区二区毛片| 五十路熟女丰满大屁股| 91在线精品一区二区三区| 青青草原av在线播放| 国产欧美日产一区| 亚洲一本大道| 欧美日韩激情小视频| 999在线精品| 亚洲成人av免费| 色在线免费视频| 在线播放/欧美激情| 亚洲制服国产| 在线观看日韩欧美| 日韩免费高清视频网站| 欧美孕妇孕交黑巨大网站| 四虎成人av| 免费电影一区| 国产乱对白刺激视频不卡| 国产日韩一区二区在线观看| 亚洲女人****多毛耸耸8| 国产视频二区在线观看| 中文字幕av一区二区三区高| 日本激情免费| 日韩欧美在线视频观看| 无码专区aaaaaa免费视频| 亚洲一区色图| 97视频在线观看免费高清完整版在线观看 | 久久精品日产第一区二区三区精品版| 国产一区二区三区色淫影院 | 亚洲高清久久| 日本精品一区二区三区视频| 国产99久久久久| www.三区| 欧美va日韩va| 国产精品任我爽爆在线播放| 波多野结衣成人在线| 国产激情91久久精品导航| 黄色片av在线| 亚洲国产精品久久91精品| 色哟哟精品丝袜一区二区| 免费久久99精品国产自| 国产亚洲精品资源在线26u| 韩国中文字幕2020精品| 久久久99久久精品女同性| 国产综合精品| 五月婷婷深爱五月| 欧美日韩不卡一区| 国产精品乱战久久久| 日韩精品不卡| 亚洲一区二区影院| 亚洲精品粉嫩美女一区| 成人精品视频99在线观看免费| 国产二区国产一区在线观看| 久久久久久久久亚洲精品| 久久精品99久久久久久久久| 亚洲人体大胆视频| 二区中文字幕| 最新91在线视频| 日韩亚洲在线| 最近中文字幕mv2018在线高清 | 国产精品国模在线| 国产盗摄女厕一区二区三区| 黄视频在线观看免费| 欧美精品免费在线| 美女一区二区视频| 国产精品久久久久久久久妇女| 日韩精品一区二区三区免费观影| 久久久久高清| 亚洲视频在线观看一区| 欧美家庭影院| 国产精品久久久久久久久男| 国产精品亚洲一区二区三区在线 | 精品中文一区| 成人在线播放网址| 337p亚洲精品色噜噜| 蜜臀91精品国产高清在线观看| 四虎4hu永久免费入口| 精品视频在线免费观看| 真实原创一区二区影院| 黄色免费视频大全| 亚洲欧美日韩一区二区三区在线| 欧美全黄视频| 在线一级观看| 国产精品成人一区二区三区吃奶| 久久久久久影视| 国产精品久久久久久久久久齐齐 | 欧美日韩亚洲一二三| 亚洲精品999| 国产亚洲福利| 国产对白叫床清晰在线播放| 国产精品久久久久久超碰| 国产精品高清亚洲| 久久久久久久久久久久电影| 亚洲激情免费视频| 亚洲第一精品久久忘忧草社区| 一本色道久久综合亚洲精品高清| 久久伊伊香蕉| 国产精品一区免费观看| 色综合视频在线观看| 欧美日韩精品| 老司机免费在线视频| 久久久久欧美| 欧美不卡一区二区三区四区| 亚洲国内欧美| 91麻豆国产福利在线观看宅福利 | 黑人一区二区三区四区五区| 在线中文字幕视频| 97视频热人人精品| 欧美日韩的一区二区| 一本久久综合| 丁香花在线高清完整版视频 | 日本高清网站| 91久久精品一区| 欧美性猛片xxxx免费看久爱| 亚洲精品偷拍| 九色porny丨国产首页在线| 午夜一区二区三区| 亚洲色图五月天| 成人av网站在线| 成人精品一区二区三区电影免费| 欧美国产日产韩国视频| 成人小视频在线观看| www.欧美| 欧美激情一二区| 亚洲视频在线一区| 97精品视频在线看| 黄色av免费在线| 亚洲免费不卡| 日韩在线精品一区| 国产精品久久久久精k8| 精品国产一区二区三区av片| 国产区在线视频| 亚洲区一区二区三区| 色偷偷88888欧美精品久久久 | 精品国产不卡一区二区| 亚洲综合色在线观看| 国产精品高清在线| 在线播放视频一区| 成人午夜免费视频| 国产精品手机在线播放| 欧美一区二区三区少妇| 在线不卡视频一区二区| 久久视频中文字幕| 亚洲一区二区三区美女| 尹人成人综合网| www.26天天久久天堂| julia京香一区二区三区| 日本亚洲导航| 午夜精品一区二区三区在线视| 欧美三级中文字| 97精品国产97久久久久久久久久久久| 精品精品久久| 女人高潮被爽到呻吟在线观看| 亚洲激情在线观看视频| 北条麻妃高清一区| 一级毛片视频在线观看| 在线观看av每日更新免费| 亚洲护士老师的毛茸茸最新章节| 国产美女av一区二区三区| 精品国产导航| 在线免费观看黄| 青青在线视频免费观看| 情事1991在线| 国产视频久久久久久久| 亚洲制服欧美中文字幕中文字幕| 亚洲综合国产激情另类一区|