电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Java并發(fā)編程之ReentrantLock可重入鎖的實(shí)例代碼

瀏覽:113日期:2022-08-17 09:42:48

目錄 1.ReentrantLock可重入鎖概述2.可重入3.可打斷4.鎖超時(shí)5.公平鎖6.條件變量 Condition

1.ReentrantLock可重入鎖概述

相對于 synchronized 它具備如下特點(diǎn)可中斷synchronized鎖加上去不能中斷,a線程應(yīng)用鎖,b線程不能取消掉它可以設(shè)置超時(shí)時(shí)間synchronized它去獲取鎖時(shí),如果對方持有鎖,那么它就會進(jìn)入entryList一直等待下去。而可重入鎖可以設(shè)置超時(shí)時(shí)間,規(guī)定時(shí)間內(nèi)如果獲取不到鎖,就放棄鎖可以設(shè)置為公平鎖防止線程饑餓的情況,即先到先得。如果爭搶的人比較多,則可能會發(fā)生永遠(yuǎn)都得不到鎖

支持多個(gè)條件變量多個(gè)waitset(不支持條件一的去a不支持條件二的去b)synchronized只支持同一個(gè)waitset.與 synchronized 一樣,都支持可重入

基本語法

// 獲取鎖reentrantLock.lock();try { // 臨界區(qū)} finally { // 釋放鎖 reentrantLock.unlock();}

synchronized是在關(guān)鍵字的級別來保護(hù)臨界區(qū),而reentrantLock是在對象的級別保護(hù)臨界區(qū)。臨界區(qū)即訪問共享資源的那段代碼。finally中表明不管將來是否出現(xiàn)異常,都會釋放鎖,釋放鎖即調(diào)用unlock方法。否則無法釋放鎖,其它線程就永遠(yuǎn)也獲取不了鎖。

2.可重入

可重入是指同一個(gè)線程如果首次獲得了這把鎖,那么因?yàn)樗沁@把鎖的擁有者,因此有權(quán)利再次獲取這把鎖如果是不可重入鎖,那么第二次獲得鎖時(shí),自己也會被鎖擋住ReentrantLock和synchronized都是可重入鎖。

public class TestReentranLock1 { static ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { method1(); } public static void method1() { lock.lock(); try { System.out.println('execute method1'); method2(); } finally { lock.unlock(); } } public static void method2() { lock.lock(); try { System.out.println('execute method2'); method3(); } finally { lock.unlock(); } } public static void method3() { lock.lock(); try { System.out.println('execute method3'); } finally { lock.unlock(); } }}

execute method1execute method2execute method33.可打斷

可打斷是指在等待鎖的過程中,其它線程可以用interrupt方法終止我的等待。synchronized鎖是不可打斷的。我們要想在等鎖的過程中被打斷,就要使用lockInterruptibly()方法對lock對象加鎖,而不是lock()方法

public class TestReentranLock2 { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Thread t1 = new Thread(() -> { try { //如果沒有競爭,此方法就會獲取lock對象的鎖 //如果有競爭,就進(jìn)入阻塞隊(duì)列等待,可以被其它線程用interrupt打斷 System.out.println('嘗試獲得鎖'); lock.lockInterruptibly(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println('等鎖的過程中被打斷'); return; } try { System.out.println('t1獲得了鎖'); } finally { lock.unlock(); } }, 't1'); lock.lock(); System.out.println('主線程獲得了鎖'); t1.start(); try { try { sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } t1.interrupt(); System.out.println('執(zhí)行打斷t1'); } finally { lock.unlock(); } }}

主線程獲得了鎖嘗試獲得鎖執(zhí)行打斷t1等鎖的過程中被打斷java.lang.InterruptedExceptionat java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)at cn.yj.jvm.TestReentranLock2.lambda$main$0(TestReentranLock2.java:15)at java.lang.Thread.run(Thread.java:748)

注意如果是不可中斷模式,那么即使使用了 interrupt 也不會讓等待中斷,即不是。即使用lock()方法。這種方式可以避免死鎖情況的發(fā)生,避免無休止的等待。

ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> { System.out.println('啟動(dòng)...'); lock.lock(); try { System.out.println('獲得了鎖'); } finally { lock.unlock(); }}, 't1');lock.lock();System.out.println('獲得了鎖');t1.start();try { sleep(1); t1.interrupt(); System.out.println('執(zhí)行打斷'); sleep(1);} finally { System.out.println('釋放了鎖'); lock.unlock();}

4.鎖超時(shí)

ReentranLock支持可打斷,其實(shí)就是為了避免死等,這樣就可以減少死鎖的發(fā)生。實(shí)際上可打斷這種方式屬于一種被動(dòng)的避免死等,是由其它線程interrupt來打斷。而鎖超時(shí)是主動(dòng)的方式避免死等的手段。獲取鎖用tryLock()方法,即嘗試獲得鎖,如果成功了,它就獲得鎖,如果失敗了,它就可以不去進(jìn)入阻塞隊(duì)列等待,它就會返回false,表示沒有獲得鎖

立刻失敗

public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Thread t1 = new Thread(() -> { System.out.println('啟動(dòng)...'); if (!lock.tryLock()) { System.out.println('獲取不到鎖,立刻失敗,返回'); return; } try { System.out.println('獲得了鎖'); } finally { lock.unlock(); } }, 't1'); lock.lock(); System.out.println('獲得了鎖'); t1.start(); try { try { sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } finally { lock.unlock(); }}

獲得了鎖啟動(dòng)...獲取不到鎖,立刻失敗,返回

超時(shí)失敗lock.tryLock(1,TimeUnit.SECONDS)表示嘗試等待1s,如果主線程不釋放鎖,那么它就會返回false,如果釋放了鎖,那么它就會返回true.tryLock也支持被打斷,被打斷時(shí)報(bào)異常

ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> { log.debug('啟動(dòng)...'); try { if (!lock.tryLock(1, TimeUnit.SECONDS)) { log.debug('獲取等待 1s 后失敗,返回'); return; } } catch (InterruptedException e) { e.printStackTrace(); } try { log.debug('獲得了鎖'); } finally { lock.unlock(); }}, 't1');lock.lock();log.debug('獲得了鎖');t1.start();try { sleep(2);} finally { lock.unlock();}

輸出

18:19:40.537 [main] c.TestTimeout - 獲得了鎖18:19:40.544 [t1] c.TestTimeout - 啟動(dòng)...18:19:41.547 [t1] c.TestTimeout - 獲取等待 1s 后失敗,返回

5.公平鎖

對于synchronized來說,它是不公平的鎖。當(dāng)一個(gè)線程持有鎖,其他線程就會進(jìn)入阻塞隊(duì)列等待,當(dāng)鎖的持有者釋放鎖的時(shí)候,這些線程就會一擁而上,誰先搶到,誰就成為monitor的主人,而不會按照先來先得的規(guī)則。

ReentrantLock 默認(rèn)是不公平的ReentrantLock有一個(gè)帶參構(gòu)造方法。默認(rèn)是非公平的。

public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync();}

我們可以通過布爾值改成真,來保證它的公平性。即將來阻塞隊(duì)列里的線程,爭搶鎖的時(shí)候會按照進(jìn)入阻塞隊(duì)列的順序執(zhí)行,先到先得

6.條件變量 Condition

synchronized 中也有條件變量,就是我們講原理時(shí)那個(gè) waitSet 休息室,當(dāng)條件不滿足時(shí)進(jìn)入 waitSet 等待

ReentrantLock 的條件變量比 synchronized 強(qiáng)大之處在于,它是支持多個(gè)條件變量的,這就好比

synchronized 是那些不滿足條件的線程都在一間休息室等消息而 ReentrantLock 支持多間休息室,有專門等煙的休息室、專門等早餐的休息室、喚醒時(shí)也是按休息室來喚醒

使用要點(diǎn):

await 前需要獲得鎖 await 執(zhí)行后,會釋放鎖,進(jìn)入 conditionObject 等待 await 的線程被喚醒(或打斷、或超時(shí))取重新競爭 lock 鎖 競爭 lock 鎖成功后,從 await 后繼續(xù)執(zhí)行 signal 相當(dāng)于 notify,signalAll 相當(dāng)于 notifyAll

static ReentrantLock lock = new ReentrantLock();static Condition waitCigaretteQueue = lock.newCondition();static Condition waitbreakfastQueue = lock.newCondition();static volatile boolean hasCigrette = false;static volatile boolean hasBreakfast = false;public static void main(String[] args) { new Thread(() -> { try { lock.lock(); while (!hasCigrette) { try { waitCigaretteQueue.await(); } catch (InterruptedException e) { e.printStackTrace(); } } log.debug('等到了它的煙'); } finally { lock.unlock(); } }).start(); new Thread(() -> { try { lock.lock(); while (!hasBreakfast) { try { waitbreakfastQueue.await(); } catch (InterruptedException e) { e.printStackTrace(); } } log.debug('等到了它的早餐'); } finally { lock.unlock(); } }).start(); sleep(1); sendBreakfast(); sleep(1); sendCigarette();}private static void sendCigarette() { lock.lock(); try { log.debug('送煙來了'); hasCigrette = true; waitCigaretteQueue.signal(); } finally { lock.unlock(); }}private static void sendBreakfast() { lock.lock(); try { log.debug('送早餐來了'); hasBreakfast = true; waitbreakfastQueue.signal(); } finally { lock.unlock(); }}

輸出

18:52:27.680 [main] c.TestCondition - 送早餐來了18:52:27.682 [Thread-1] c.TestCondition - 等到了它的早餐18:52:28.683 [main] c.TestCondition - 送煙來了18:52:28.683 [Thread-0] c.TestCondition - 等到了它的煙

到此這篇關(guān)于Java并發(fā)編程之ReentrantLock可重入鎖的實(shí)例代碼的文章就介紹到這了,更多相關(guān)Java ReentrantLock可重入鎖內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 矿用履带式平板车|探水钻机|气动架柱式钻机|架柱式液压回转钻机|履带式钻机-启睿探水钻机厂家 | 大学食堂装修设计_公司餐厅效果图_工厂食堂改造_迈普装饰 | 单电机制砂机,BHS制砂机,制沙机设备,制砂机价格-正升制砂机厂家 单级/双级旋片式真空泵厂家,2xz旋片真空泵-浙江台州求精真空泵有限公司 | 植筋胶-粘钢胶-碳纤维布-碳纤维板-环氧砂浆-加固材料生产厂家-上海巧力建筑科技有限公司 | 知企服务-企业综合服务(ZiKeys.com)-品优低价、种类齐全、过程管理透明、速度快捷高效、放心服务,知企专家! | 齿轮减速机_齿轮减速电机-VEMT蜗轮蜗杆减速机马达生产厂家瓦玛特传动瑞环机电 | 安徽华耐泵阀有限公司-官方网站 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 杭州月嫂技术培训服务公司-催乳师培训中心报名费用-产后康复师培训机构-杭州优贝姆健康管理有限公司 | 温州食堂承包 - 温州市尚膳餐饮管理有限公司 | 氨水-液氨-工业氨水-氨水生产厂家-辽宁顺程化工 | 开平机_纵剪机厂家_开平机生产厂家|诚信互赢-泰安瑞烨精工机械制造有限公司 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库-首页-东莞市傲马网络科技有限公司 | PE一体化污水处理设备_地埋式生活污水净化槽定制厂家-岩康塑业 | 档案密集柜_手动密集柜_智能密集柜_内蒙古档案密集柜-盛隆柜业内蒙古密集柜直销中心 | ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | 专业生物有机肥造粒机,粉状有机肥生产线,槽式翻堆机厂家-郑州华之强重工科技有限公司 | 广州云仓代发-昊哥云仓专业电商仓储托管外包代发货服务 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 烟雾净化器-滤筒除尘器-防爆除尘器-除尘器厂家-东莞执信环保科技有限公司 | 银川美容培训-美睫美甲培训-彩妆纹绣培训-新娘化妆-学化妆-宁夏倍莱妮职业技能培训学校有限公司 临时厕所租赁_玻璃钢厕所租赁_蹲式|坐式厕所出租-北京慧海通 | 广州市哲铭油墨涂料有限公司,水性漆生产研发基地 | 佛山市钱丰金属不锈钢蜂窝板定制厂家|不锈钢装饰线条|不锈钢屏风| 电梯装饰板|不锈钢蜂窝板不锈钢工艺板材厂家佛山市钱丰金属制品有限公司 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | 济南网站策划设计_自适应网站制作_H5企业网站搭建_济南外贸网站制作公司_锐尚 | 热工多功能信号校验仪-热电阻热电偶校验仿真仪-金湖虹润仪表 | 工业淬火油烟净化器,北京油烟净化器厂家,热处理油烟净化器-北京众鑫百科 | 一氧化氮泄露报警器,二甲苯浓度超标报警器-郑州汇瑞埔电子技术有限公司 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 耐高温硅酸铝板-硅酸铝棉保温施工|亿欧建设工程 | 选矿设备-新型重选设备-金属矿尾矿重选-青州冠诚重工机械有限公司 | Type-c防水母座|贴片母座|耳机接口|Type-c插座-深圳市步步精科技有限公司 | 暖气片十大品牌厂家_铜铝复合暖气片厂家_暖气片什么牌子好_欣鑫达散热器 | 生物颗粒燃烧机-生物质燃烧机-热风炉-生物颗粒蒸汽发生器-丽水市久凯能源设备有限公司 | 七维官网-水性工业漆_轨道交通涂料_钢结构漆 | 耐火砖厂家,异形耐火砖-山东瑞耐耐火材料厂| 上海地磅秤|电子地上衡|防爆地磅_上海地磅秤厂家–越衡称重 | 硬度计_影像测量仪_维氏硬度计_佛山市精测计量仪器设备有限公司厂家 | 变位机,焊接变位机,焊接变位器,小型变位机,小型焊接变位机-济南上弘机电设备有限公司 | 防水套管_柔性防水套管_刚性防水套管-巩义市润达管道设备制造有限公司 | 带式过滤机厂家_价格_型号规格参数-江西核威环保科技有限公司 |