日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

沒看過ReentrantLock源碼,別說精通Java并發編程

來源: 責編: 時間:2024-03-18 09:36:21 179觀看
導讀引言高手程序員與新手程序員一個簡單的判斷標準,就是有沒有使用過CountDownLatch,在互聯網公司工作超過3年的程序員基本上應該都用過。CountDownLatch中文名稱叫做閉鎖,也叫計數鎖,不過不是用來加鎖的,而是通過計數實現條

引言

高手程序員與新手程序員一個簡單的判斷標準,就是有沒有使用過CountDownLatch,在互聯網公司工作超過3年的程序員基本上應該都用過。CountDownLatch中文名稱叫做閉鎖,也叫計數鎖,不過不是用來加鎖的,而是通過計數實現條件等待的功能。CountDownLatch的使用場景有兩個:9GR28資訊網——每日最新資訊28at.com

  1. 當前線程等待其他線程都執行完成之后,再執行。
  2. 所有線程滿足條件后,再一起執行。

使用示例

CountDownLatch常用的方法就兩個,countDown()方法用來將計數器減一,await()方法會阻塞當前線程,直到計數器值等于0。9GR28資訊網——每日最新資訊28at.com

場景1:

先看一下第一種場景,也是最常用的場景:9GR28資訊網——每日最新資訊28at.com

  • 當前線程等待其他線程都執行完成之后,再執行。

在工作中什么時候會遇到這種場景呢?比如當前線程需要查詢3個數據庫,并且把查詢結果匯總返回給前端。查詢3個數據庫的邏輯,可以分別使用3個線程加快查詢速度。但是怎么判斷3個線程都執行結束了呢?這時候就可以使用CountDownLatch了。9GR28資訊網——每日最新資訊28at.com

import java.util.concurrent.CountDownLatch;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * @author 一燈架構 * @apiNote CountDownLatch測試類(場景1) **/public class CountDownLatchTest1 {    public static void main(String[] args) throws InterruptedException {        // 1. 創建一個線程池,用來執行3個查詢任務        ExecutorService executorService = Executors.newFixedThreadPool(3);        // 2. 創建一個計數鎖,數量是3        CountDownLatch countDownLatch = new CountDownLatch(3);        // 3. 啟動3個查詢任務        for (int i = 0; i < 3; i++) {            executorService.submit(() -> {                try {                    // 4. 睡眠1秒,模擬任務執行過程                    Thread.sleep(1000);                    System.out.println(Thread.currentThread().getName() + " 執行完成");                    // 5. 任務執行完成,計數器減一                    countDownLatch.countDown();                } catch (InterruptedException e) {                }            });        }        // 6. 等待所有任務執行完成        countDownLatch.await();        System.out.println("所有任務執行完成。");        // 7. 關閉線程池        executorService.shutdown();    }}

輸出結果:9GR28資訊網——每日最新資訊28at.com

pool-1-thread-2 執行完成 pool-1-thread-1 執行完成 pool-1-thread-3 執行完成 所有任務執行完成。9GR28資訊網——每日最新資訊28at.com

需要注意的是,這里創建CountDownLatch計數器的時候,指定的數量是3,因為有3個任務。在3個任務沒有執行完成之前,await()方法會一直阻塞,直到3個任務都執行完成。9GR28資訊網——每日最新資訊28at.com

場景2

再看一下第二種場景,有些情況用的也比較多:9GR28資訊網——每日最新資訊28at.com

  • 所有線程滿足條件后,再一起執行。

什么情況下會遇到這種場景呢?比如系統中多個任務線程存在先后依賴關系,必須等待其他線程啟動完成后,才能一起執行。9GR28資訊網——每日最新資訊28at.com

/** * @author 一燈架構 * @apiNote CountDownLatch測試類(場景2) **/public class CountDownLatchTest {    public static void main(String[] args) throws InterruptedException {        // 1. 創建一個線程池,用來執行3個任務        ExecutorService executorService = Executors.newFixedThreadPool(3);        // 2. 創建一個計數鎖,數量是1        CountDownLatch countDownLatch = new CountDownLatch(1);        // 3. 啟動3個任務        for (int i = 0; i < 3; i++) {            executorService.submit(() -> {                try {                    System.out.println(Thread.currentThread().getName() + " 啟動完成");                    // 4. 等待其他任務啟動完成                    countDownLatch.await();                    // 5. 睡眠1秒,模擬任務執行過程                    Thread.sleep(1000);                    System.out.println(Thread.currentThread().getName() + " 執行完成");                } catch (InterruptedException e) {                }            });        }        // 6. 所有任務啟動完成,計數器減一        countDownLatch.countDown();        System.out.println("所有任務啟動完成,開始執行。");        // 7. 關閉線程池        executorService.shutdown();    }}

輸出結果:9GR28資訊網——每日最新資訊28at.com

pool-1-thread-1 啟動完成 pool-1-thread-2 啟動完成 pool-1-thread-3 啟動完成 所有任務啟動完成,開始執行。 pool-1-thread-1 執行完成 pool-1-thread-3 執行完成 pool-1-thread-2 執行完成9GR28資訊網——每日最新資訊28at.com

需要注意的是,與場景1不同,這里創建CountDownLatch計數器的時候,指定的數量是1,因為3個任務需要滿足同一個條件,就是都啟動完成,也就是只需要調用一次countDown()方法。 看完了CountDownLatch的使用方式,再看一下CountDownLatch的源碼實現。9GR28資訊網——每日最新資訊28at.com

類屬性

public class CountDownLatch {    // 只有一個Sync同步變量    private final Sync sync;    // Sync繼承自AQS,主要邏輯都在這里面    private static final class Sync extends AbstractQueuedSynchronizer {        // 只有這一個構造方法,需要指定計數器數值        Sync(int count) {            setState(count);        }        int getCount() {            return getState();        }        protected int tryAcquireShared(int acquires) {            return (getState() == 0) ? 1 : -1;        }        protected boolean tryReleaseShared(int releases) {            for (;;) {                int c = getState();                if (c == 0)                    return false;                int nextc = c-1;                if (compareAndSetState(c, nextc))                    return nextc == 0;            }        }    }}

跟ReentrantLock一樣,CountDownLatch也沒有直接繼承AQS,也是采用組合的方式,使用Sync同步變量實現計數的功能,而Sync同步變量才是真正繼承AQS的。9GR28資訊網——每日最新資訊28at.com

countDown方法源碼

public void countDown() {    // 底層調用父類AQS中的releaseShared()方法    sync.releaseShared(1);}

countDown()方法里面調用的是父類AQS中的releaseShared()方法,而releaseShared()方法又在調用子類Sync中tryReleaseShared()方法。9GR28資訊網——每日最新資訊28at.com

/** * 父類AQS */public abstract class AbstractQueuedSynchronizer        extends AbstractOwnableSynchronizer        implements java.io.Serializable {                public final boolean releaseShared(int arg) {        // tryReleaseShared()由子類實現        if (tryReleaseShared(arg)) {            doReleaseShared();            return true;        }        return false;    }    // 定義抽象方法,由子類實現    protected boolean tryReleaseShared(int arg) {        throw new UnsupportedOperationException();    }}
/** * 子類Sync */private static final class Sync extends AbstractQueuedSynchronizer {        // 實現父類AQS中的tryReleaseShared()方法    @Override    protected boolean tryReleaseShared(int releases) {        for (;;) {            int c = getState();            if (c == 0) {                return false;            }            int nextc = c-1;            if (compareAndSetState(c, nextc)) {                return nextc == 0;            }        }    }}

而Sync同步類中tryReleaseShared()方法邏輯也很簡單,就是把同步狀態state值減一。9GR28資訊網——每日最新資訊28at.com

await源碼

await()方法底層也是調用父類中acquireSharedInterruptibly()方法,而父類AQS又需要調用子類Sync中的具體實現。9GR28資訊網——每日最新資訊28at.com

public void await() throws InterruptedException {    // 底層調用父類AQS中的releaseShared()方法    sync.acquireSharedInterruptibly(1);}
/** * 父類AQS */public abstract class AbstractQueuedSynchronizer        extends AbstractOwnableSynchronizer        implements java.io.Serializable {    public final void acquireSharedInterruptibly(int arg) throws InterruptedException {        if (Thread.interrupted()) {            throw new InterruptedException();        }        // tryAcquireShared()由子類實現        if (tryAcquireShared(arg) < 0) {            doAcquireSharedInterruptibly(arg);        }    }    // 定義抽象方法,由子類實現    protected int tryAcquireShared(int arg) {        throw new UnsupportedOperationException();    }}

子類Sync只需要實現tryAcquireShared()方法即可,而tryAcquireShared()方法的作用就是判斷鎖是否已經完全釋放,即同步狀態state=0。9GR28資訊網——每日最新資訊28at.com

/** * 子類Sync */private static final class Sync extends AbstractQueuedSynchronizer {    // 實現父類AQS中的tryAcquireShared()方法    @Override    protected int tryAcquireShared(int acquires) {        return (getState() == 0) ? 1 : -1;    }}

總結

看完了CountDownLatch的所有源碼,是不是覺得CountDownLatch邏輯很簡單。9GR28資訊網——每日最新資訊28at.com

因為加鎖流程的編排工作已經在父類AQS中實現,子類只需要實現具體的加鎖邏輯即可,也就是實現tryReleaseShared()方法和tryAcquireShared()方法。而加鎖邏輯也很簡單,也就是修改同步狀態state的值即可。想要詳細了解父類AQS的流程,可以翻看前幾篇文章。9GR28資訊網——每日最新資訊28at.com

下篇文章再一塊學習一下共享鎖Semaphore的源碼實現。9GR28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-76485-0.html沒看過ReentrantLock源碼,別說精通Java并發編程

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 工作中最常見的六種OOM問題

下一篇: 一個很有意思的Spring注入問題,你遇到過嗎?

標簽:
  • 熱門焦點
  • 7月安卓手機性能榜:紅魔8S Pro再奪榜首

    7月份的手機市場風平浪靜,除了紅魔和努比亞帶來了兩款搭載驍龍8Gen2領先版處理器的新機之外,別的也想不到有什么新品了,這也正常,通常6月7月都是手機廠商修整的時間,進入8月份之
  • 容量越大越不壞?24萬塊硬盤故障率報告公布 這些產品零故障

    8月5日消息,云存儲服務商Backblaze發布了最新的硬盤故障率報告,年故障率有所上升。Backblaze發布的硬盤季度統計數據,其中包括故障率等重要方面。這些結
  • 一加首款折疊屏!一加Open渲染圖出爐:罕見單手可握小尺寸

    8月5日消息,此前就有爆料稱,一加首款折疊屏手機將會在第三季度上市,如今隨著時間臨近,新機的各種消息也開始浮出水面。據悉,這款新機將會被命名為&ldquo;On
  • 如何通過Python線程池實現異步編程?

    線程池的概念和基本原理線程池是一種并發處理機制,它可以在程序啟動時創建一組線程,并將它們置于等待任務的狀態。當任務到達時,線程池中的某個線程會被喚醒并執行任務,執行完任
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務,包括但不限于:開發某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 騰訊蓋樓,字節拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • 新電商三兄弟,“抖快紅”成團!

    來源:價值研究所作 者:Hernanderz 隨著內容電商的概念興起,抖音、快手、小紅書組成的&ldquo;新電商三兄弟&rdquo;成為業內一股不可忽視的勢力,給阿里、京東、拼多多帶去了巨大壓
  • AMD的AI芯片轉單給三星可能性不大 與臺積電已合作至2nm制程

    據 DIGITIMES 消息,英偉達 AI GPU 出貨逐季飆升,接下來 AMD MI 300 系列將在第 4 季底量產。而半導體業內人士表示,近日傳出 AMD 的 AI 芯片將轉單給
  • iQOO 11S新品發布會

    iQOO將在7月4日19:00舉行新品發布會,推出杭州亞運會電競賽事官方用機iQOO 11S。
Top 主站蜘蛛池模板: 香格里拉县| 满洲里市| 大荔县| 璧山县| 桐乡市| 新田县| 明光市| 深水埗区| 黔东| 泰来县| 谢通门县| 临邑县| 图片| 栾川县| 成都市| 麦盖提县| 汶上县| 革吉县| 襄汾县| 陆川县| 峨眉山市| 侯马市| 东乌珠穆沁旗| 拜泉县| 额敏县| 司法| 山阳县| 紫云| 云阳县| 牡丹江市| 兴仁县| 滁州市| 嘉峪关市| 云安县| 凤阳县| 彝良县| 奉化市| 合山市| 峨边| 江都市| 罗定市|