Java中的鎖ReentrantLock詳解
一、 ReentrantLock使用
1.1 簡單使用
public class LockTest { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 測試 LockTest test = new LockTest(); test.te(); } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("獲取到鎖執(zhí)行代碼!"); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中釋放鎖 lock.unlock(); } } }
1.2 tryLock
Lock比synchronized還是多一些功能的,比如可以設(shè)置規(guī)定時間內(nèi)獲取不到鎖就返回,不一直阻塞。
一個不合時宜的例子就是:
synchronize就是一個舔狗,一直舔 直到天荒地老
lock 的 tryLock 就像是一個渣男,輕輕嘗試一下,不合適抓緊下一個
public class LockTest02 { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) { // 測試 LockTest02 test = new LockTest02(); new Thread(()->test.te()).start(); // test::teTryLock lambda寫法 new Thread(test::teTryLock).start(); } private void teTryLock() { boolean res = false; try { // 嘗試獲取 5秒鐘獲取不到就結(jié)束 res = lock.tryLock(5,TimeUnit.SECONDS); if (res) { System.out.println("teTryLock獲取到鎖了,執(zhí)行獲取到鎖的代碼"); } else{ System.out.println("teTryLock沒有獲取到鎖 執(zhí)行沒有獲取到鎖的代碼"); } } catch (Exception e) { e.printStackTrace(); } finally { // 如果獲取到鎖了 再釋放 if (res) { lock.unlock(); } } } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("te獲取到鎖執(zhí)行代碼!"); Thread.sleep(10000); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中釋放鎖 lock.unlock(); System.out.println("te釋放鎖!"); } } }
輸出結(jié)果:
te獲取到鎖執(zhí)行代碼!
teTryLock沒有獲取到鎖 執(zhí)行沒有獲取到鎖的代碼
te釋放鎖!
1.3 lockInterruptibly
synchronized 如果開始等待是不能結(jié)束的
但是Lock使用lockInterruptibly 可以被中斷 在異常捕獲里捕獲異常 然后做一些后置處理
public class LockTest03 { // 新建鎖 Lock lock = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { // 測試 LockTest03 test = new LockTest03(); new Thread(test::te).start(); Thread thread = new Thread(test::teLockInterruptibly); thread.start(); Thread.sleep(3000); thread.interrupt(); } private void teLockInterruptibly() { boolean res = true; try { // 嘗試獲取 5秒鐘獲取不到就結(jié)束 lock.lockInterruptibly(); System.out.println("獲取到鎖··"); } catch (InterruptedException e) { //沒有正常獲取鎖 被Interrupt了 res = false; System.out.println("InterruptedException:被打斷了 做一些其他處理"); } finally { // 如果沒被打斷 是正常獲取鎖的(理論上是,也可能有其他異常) if(res) { lock.unlock(); } } } public void te(){ try { // 獲取鎖 lock.lock(); System.out.println("te獲取到鎖執(zhí)行代碼!"); // te 方法睡死過去了 Thread.sleep(10000000); } catch (Exception e) { e.printStackTrace(); } finally { // 一定注意 在finally中釋放鎖 lock.unlock(); System.out.println("te釋放鎖!"); } } }
1.4 公平鎖
synchronized是非公平鎖 后來的也可能會先獲取到鎖
Lock鎖默認(rèn)也是非公平鎖
非公平鎖是什么樣的?
用不要臉的小強(qiáng)來做比喻,假設(shè)有10個人在排隊買餅,小強(qiáng)這時候也來買餅了,不要臉的他直接跑第一個位置,這時候如果正有人在選餅,那他就灰溜溜的走了,如果上一個人剛好買完,下一個人還沒有開始選,那不要臉的小強(qiáng)就會趁著這個間隙直接跟老板選餅. 這樣對于后邊排隊的是不公平的 所以稱為不公平鎖
在ReentrantLock的實現(xiàn)中,不要臉的小強(qiáng)會嘗試好幾次,最后都失敗的話他才會去隊尾排隊
Lock可以實現(xiàn)公平鎖:公平鎖就是lock的時候會先去排隊隊列里邊看看,有沒有人在排隊,有的話站后邊去,可以看我寫過的AQS ,用公平鎖做的舉例 講到了源碼層
注意:公平鎖不是完全公平,公平鎖只是會檢查隊列里有沒有人排隊,如果沒有自己去申請鎖,如果有自己去排隊,去檢查有沒有人排隊的時候可能會出現(xiàn)不公平(地鐵一個人一大步竄你前邊了),進(jìn)隊列的時候也可能會出現(xiàn)不公平(地鐵一個人一大步竄你前邊了)
Lock lock = new ReentrantLock(true); // true表示公平
到此這篇關(guān)于Java中的鎖ReentrantLock詳解的文章就介紹到這了,更多相關(guān)ReentrantLock詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于springboot服務(wù)間Feign調(diào)用超時的解決方案
這篇文章主要介紹了基于springboot服務(wù)間Feign調(diào)用超時的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07PowerJob的DatabaseMonitorAspect源碼流程
這篇文章主要為大家介紹了PowerJob的DatabaseMonitorAspect源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Java高效提取PDF文件指定坐標(biāo)的文本內(nèi)容實戰(zhàn)代碼
在日常工作中,有時可能會需要從龐大的PDF文檔中提取其中所包含的文本內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于如何利用Java高效提取PDF文件指定坐標(biāo)的文本內(nèi)容,需要的朋友可以參考下2024-01-01Java 中Comparable和Comparator區(qū)別比較
本文,先介紹Comparable 和Comparator兩個接口,以及它們的差異;接著,通過示例,對它們的使用方法進(jìn)行說明2013-09-09springmvc學(xué)習(xí)筆記-返回json的日期格式問題的解決方法
本篇文章主要介紹了springmvc學(xué)習(xí)筆記-返回json的日期格式問題的解決方法,解決了日期格式的輸出,有興趣的可以了解一下。2017-01-01Mybatis中一對多(collection)和一對一(association)的組合查詢使用
這篇文章主要介紹了Mybatis中一對多(collection)和一對一(association)的組合查詢使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12基于Java的Spring框架來操作FreeMarker模板的示例
這篇文章主要介紹了基于Java的Spring框架來操作FreeMarker模板的示例,講到了用于進(jìn)行web模板文件的插值操作等例子,需要的朋友可以參考下2016-03-03