日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:198日期: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('啟動...'); 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í)際上可打斷這種方式屬于一種被動的避免死等,是由其它線程interrupt來打斷。而鎖超時(shí)是主動的方式避免死等的手段。獲取鎖用tryLock()方法,即嘗試獲得鎖,如果成功了,它就獲得鎖,如果失敗了,它就可以不去進(jìn)入阻塞隊(duì)列等待,它就會返回false,表示沒有獲得鎖

立刻失敗

public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Thread t1 = new Thread(() -> { System.out.println('啟動...'); 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(); }}

獲得了鎖啟動...獲取不到鎖,立刻失敗,返回

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

ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> { log.debug('啟動...'); 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 - 啟動...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)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久精品国内一区二区三区| 激情婷婷久久| 三级在线观看一区二区| 在线亚洲一区| 亚洲香蕉久久| 亚洲色图综合| 亚洲一二三区视频| 天堂av一区| 欧美精品国产白浆久久久久| 7777精品| 日韩一区三区| 石原莉奈一区二区三区在线观看| 亚洲日韩视频| 麻豆精品视频在线| 日韩中文影院| 日韩中文字幕不卡| 美女在线视频一区| 日本免费一区二区三区四区| 激情婷婷亚洲| 亚洲精品在线国产| 中文字幕系列一区| 婷婷精品视频| 亚洲一区二区三区高清| 日本在线成人| 在线手机中文字幕| 久久国产精品毛片| 国产精品毛片久久久| 五月激情久久| 日韩专区在线视频| 国产999精品在线观看| 伊人精品一区| 久久亚洲影院| 日韩视频不卡| 久久av网址| 天堂成人免费av电影一区| 国产精品久一| 99热精品在线| 美女视频黄久久| 亚洲有吗中文字幕| 欧美亚洲精品在线| 麻豆精品视频在线观看| 乱人伦精品视频在线观看| 高清一区二区三区av| 日本电影久久久| 蜜桃成人av| 日韩欧美二区| 久久99免费视频| 亚洲日本欧美| 亚洲一区二区三区四区五区午夜 | 国产v综合v| 国产精品久久久久av蜜臀| 欧美中文日韩| 欧美特黄视频| 国产韩日影视精品| 99成人在线视频| 中文字幕在线高清| 欧美国产偷国产精品三区| 国产精品免费不| 国产探花在线精品| 国产乱人伦精品一区| 青青草精品视频| 中文字幕亚洲在线观看| 爽好久久久欧美精品| 亚洲免费在线| 日韩在线观看一区| 精品午夜久久| 天堂√8在线中文| 快播电影网址老女人久久| 激情综合自拍| 亚洲深夜福利| 一区二区三区午夜视频| 亚洲免费成人av在线| 日韩成人一级| 久久国产生活片100| 国产亚洲一卡2卡3卡4卡新区| 97精品久久| 精品国产aⅴ| 日韩福利一区| 国产精品三级| 亚洲免费激情| 中文无码日韩欧| 欧美69视频| 亚洲女同一区| 日韩精品视频中文字幕| 久久精品网址| 不卡av一区二区| 欧美日韩一区二区三区不卡视频| 国产精品久久久久久久久久齐齐 | 天堂日韩电影| 国产精品美女久久久| 石原莉奈在线亚洲二区| 日韩欧美在线精品| 国产一区二区三区久久| 久久中文字幕二区| 日韩精品三区四区| 久久国产欧美| 91精品丝袜国产高跟在线| 国产成人精品一区二区三区视频| 久久久精品久久久久久96 | 快she精品国产999| 美女高潮久久久| 在线亚洲国产精品网站| 久久亚洲电影| 精品网站999| 日本午夜精品一区二区三区电影| 国产在线视频欧美一区| 蜜桃视频第一区免费观看| 日韩超碰人人爽人人做人人添| 成人污污视频| 蜜臀av一区二区在线免费观看| 久久国产精品美女| 视频一区二区三区在线| 日韩av福利| 麻豆91精品视频| 美女精品网站| 欧美aa一级| 久久不见久久见免费视频7 | 日本不良网站在线观看| 亚洲精品三级| 午夜久久一区| 日韩免费看片| 日韩1区在线| 国产精品qvod| 欧美伊人影院| 91亚洲精品在看在线观看高清| 亚洲精品国产偷自在线观看| 另类专区亚洲| 国产精品毛片久久| 美女视频网站久久| 日本不卡视频一二三区| 免费国产自线拍一欧美视频| 极品日韩av| 在线看片不卡| 快she精品国产999| 蜜臀久久久99精品久久久久久| 国产精品美女久久久浪潮软件| 99精品视频在线| 欧美成人日韩| 美女久久一区| 日韩在线视频一区二区三区| 亚洲精品激情| 欧美精品1区| 日本高清不卡一区二区三区视频 | 99综合视频| 在线观看一区| 欧美一区网站| 国产一区二区三区天码| 久久精品国产久精国产| 国产在线不卡一区二区三区| 日本不卡免费高清视频在线| 成人羞羞视频播放网站| 尤物精品在线| 日本成人在线不卡视频| 精品国产一区二区三区av片| 女生影院久久| 亚洲精品少妇| 久久影视三级福利片| 欧美国产美女| 国产精品丝袜xxxxxxx| 91麻豆精品| 亚洲成人va| 免费观看日韩电影| 高清日韩欧美| 一区二区三区四区在线观看国产日韩 | 欧美一区二区性| 蜜桃传媒麻豆第一区在线观看 | 久久久91麻豆精品国产一区| 色综合五月天| 水蜜桃久久夜色精品一区的特点| 国产精品成人一区二区网站软件| 人人香蕉久久| 国产精品一区毛片| 999在线观看精品免费不卡网站| 视频精品一区| 亚洲欧美一区在线| 久久精品理论片| 亚洲人亚洲人色久| 欧美日韩精品免费观看视频完整| 国产欧美日韩影院| 老鸭窝毛片一区二区三区| 日韩精品网站| 精品九九久久| 婷婷成人av| 国产精品av一区二区| 麻豆传媒一区二区三区| 欧美一级网址| 亚洲久久视频| 免费精品视频| 好看不卡的中文字幕| 亚洲一级少妇| 福利视频一区| 精品日韩一区| 国产精品jk白丝蜜臀av小说| 久久aⅴ国产紧身牛仔裤| 国产精选一区| 国产精品婷婷| 91成人精品视频| 精品伊人久久| 日韩久久一区| 日韩精品一区二区三区av|