摘要:中提供了幾個(gè)比較常用的并發(fā)工具類,比如。是一個(gè)同步工具類,它允許一個(gè)或多個(gè)線程一直等待,直到其他線程的操作執(zhí)行完畢再執(zhí)行。從命名可以解讀到是倒數(shù)的意思,類似于我們倒計(jì)時(shí)的概念。
JUC中提供了幾個(gè)比較常用的并發(fā)工具類,比如CountDownLatch、CyclicBarrier、Semaphore。 其實(shí)在以前我們 課堂的演示代碼中,或多或少都有用到過(guò)這樣一些api,接下來(lái)我們會(huì)帶大家去深入研究一些常用的api。 CountDownLatch
countdownlatch是一個(gè)同步工具類,它允許一個(gè)或多個(gè)線程一直等待,直到其他線程的操作執(zhí)行完畢再執(zhí)行。從 命名可以解讀到countdown是倒數(shù)的意思,類似于我們倒計(jì)時(shí)的概念。 countdownlatch提供了兩個(gè)方法,一個(gè)是countDown,一個(gè)是await, countdownlatch初始化的時(shí)候需要傳入一 個(gè)整數(shù),在這個(gè)整數(shù)倒數(shù)到0之前,調(diào)用了await方法的程序都必須要等待,然后通過(guò)countDown來(lái)倒數(shù)。
public static void main(String[] args) throws InterruptedException { ? ?CountDownLatch countDownLatch=new CountDownLatch(3); ? ?new Thread(()->{ ? ? ? ? ? ?countDownLatch.countDown(); ? },"t1").start(); ? ?new Thread(()->{ ? ? ? ? ? ?countDownLatch.countDown(); ? },"t2").start(); ? ?new Thread(()->{ ? ? ? ?countDownLatch.countDown(); ? },"t3").start(); ? ?countDownLatch.await(); ? ?System.out.println("所有線程執(zhí)行完畢"); }
從代碼的實(shí)現(xiàn)來(lái)看,有點(diǎn)類似join的功能,但是比join更加靈活。CountDownLatch構(gòu)造函數(shù)會(huì)接收一個(gè)int類型的 參數(shù)作為計(jì)數(shù)器的初始值,當(dāng)調(diào)用CountDownLatch的countDown方法時(shí),這個(gè)計(jì)數(shù)器就會(huì)減一。 通過(guò)await方法去阻塞去阻塞主流程
使用場(chǎng)景
1. 通過(guò)countdownlatch實(shí)現(xiàn)最大的并行請(qǐng)求,也就是可以讓N個(gè)線程同時(shí)執(zhí)行,這個(gè)我也是在課堂上寫(xiě)得比較多 的
2. 比如應(yīng)用程序啟動(dòng)之前,需要確保相應(yīng)的服務(wù)已經(jīng)啟動(dòng),比如我們之前在講zookeeper的時(shí)候,通過(guò)原生api連 接的地方有用到countDownLatch 源碼分析
CountDownLatch類存在一個(gè)內(nèi)部類Sync,上節(jié)課我們講過(guò),它是一個(gè)同步工具,一定繼承了 AbstractQueuedSynchronizer。很顯然,CountDownLatch實(shí)際上是是使得線程阻塞了,既然涉及到阻塞,就一 定涉及到AQS隊(duì)列 await
await函數(shù)會(huì)使得當(dāng)前線程在countdownlatch倒計(jì)時(shí)到0之前一直等待,除非線程別中斷;從源碼中可以得知await 方法會(huì)轉(zhuǎn)發(fā)到Sync的acquireSharedInterruptibly
方法
public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } acquireSharedInterruptibly
這塊代碼主要是判斷當(dāng)前線程是否獲取到了共享鎖; 上一節(jié)課提到過(guò),AQS有兩種鎖類型,一種是共享鎖,一種是 獨(dú)占鎖,在這里用的是共享鎖; 為什么要用共享鎖,因?yàn)镃ountDownLatch可以多個(gè)線程同時(shí)通過(guò)。
public final void acquireSharedInterruptibly(int arg) ? ? ? ?throws InterruptedException { doAcquireSharedInterruptibly 獲取共享鎖 ? ?if (Thread.interrupted()) //判斷線程是否中斷 ? ? ? ?throw new InterruptedException(); ? ?if (tryAcquireShared(arg) < 0) //如果等于0則返回1,否則返回-1,返回-1表示需要阻塞 ? ? ? ?doAcquireSharedInterruptibly(arg); } 在這里,state的意義是count,如果計(jì)數(shù)器為0,表示不需要阻塞,否則,只有在滿足條件的情況下才會(huì)被喚醒
doAcquireSharedInterruptibly
獲取共享鎖
private void doAcquireSharedInterruptibly(int arg) ? ?throws InterruptedException { ? ?final Node node = addWaiter(Node.SHARED); //創(chuàng)建一個(gè)共享模式的節(jié)點(diǎn)添加到隊(duì)列中 ? ?boolean failed = true; ? ?try { ? ? ? ?for (;;) { //自旋等待共享鎖釋放,也就是等待計(jì)數(shù)器等于0。 ? ? ? ? ? ?final Node p = node.predecessor(); //獲得當(dāng)前節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn) ? ? ? ? ? ?if (p == head) { ? ? ? ? ? ? ? ?int r = tryAcquireShared(arg);//就判斷嘗試獲取鎖 ? ? ? ? ? ? ? ?if (r >= 0) {//r>=0表示計(jì)數(shù)器已經(jīng)歸零了,則釋放當(dāng)前的共享鎖 ? ? ? ? ? ? ? ? ? ?setHeadAndPropagate(node, r); ? ? ? ? ? ? ? ? ? ?p.next = null; // help GC ? ? ? ? ? ? ? ? ? ?failed = false; ? ? ? ? ? ? ? ? ? ?return; ? ? ? ? ? ? ? } ? ? ? ? ? } //當(dāng)前節(jié)點(diǎn)不是頭節(jié)點(diǎn),則嘗試讓當(dāng)前線程阻塞,第一個(gè)方法是判斷是否需要阻塞,第二個(gè)方法是阻塞 ? ? ? ? ? ?if (shouldParkAfterFailedAcquire(p, node) && ? ? ? ? ? ? ? ?parkAndCheckInterrupt()) ? ? ? ? ? ? ? ?throw new InterruptedException(); ? ? ? } ? } finally { ? ? ? ?if (failed) ? ? ? ? ? ?cancelAcquire(node); ? } }
待續(xù)。。。。。。。。。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72632.html
摘要:在上篇文章實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)框架單任務(wù)版爬蟲(chóng)中我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單任務(wù)版爬蟲(chóng),對(duì)于單任務(wù)版爬蟲(chóng),每次都要請(qǐng)求頁(yè)面,然后解析數(shù)據(jù),然后才能請(qǐng)求下一個(gè)頁(yè)面。在上篇文章Golang實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)框架(2)——單任務(wù)版爬蟲(chóng)中我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單任務(wù)版爬蟲(chóng),對(duì)于單任務(wù)版爬蟲(chóng),每次都要請(qǐng)求頁(yè)面,然后解析數(shù)據(jù),然后才能請(qǐng)求下一個(gè)頁(yè)面。整個(gè)過(guò)程中,獲取網(wǎng)頁(yè)數(shù)據(jù)速度比較慢,那么我們就把獲取數(shù)據(jù)模塊做成并發(fā)執(zhí)行。在...
摘要:在上篇文章實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)框架單任務(wù)版爬蟲(chóng)中我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單任務(wù)版爬蟲(chóng),對(duì)于單任務(wù)版爬蟲(chóng),每次都要請(qǐng)求頁(yè)面,然后解析數(shù)據(jù),然后才能請(qǐng)求下一個(gè)頁(yè)面。在上篇文章Golang實(shí)現(xiàn)簡(jiǎn)單爬蟲(chóng)框架(2)——單任務(wù)版爬蟲(chóng)中我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的單任務(wù)版爬蟲(chóng),對(duì)于單任務(wù)版爬蟲(chóng),每次都要請(qǐng)求頁(yè)面,然后解析數(shù)據(jù),然后才能請(qǐng)求下一個(gè)頁(yè)面。整個(gè)過(guò)程中,獲取網(wǎng)頁(yè)數(shù)據(jù)速度比較慢,那么我們就把獲取數(shù)據(jù)模塊做成并發(fā)執(zhí)行。在...
摘要:如何使用優(yōu)化高并發(fā)場(chǎng)景寫(xiě)庫(kù)或者耗時(shí)計(jì)算在的接口中使用消息隊(duì)列,把要入庫(kù)的數(shù)據(jù)寫(xiě)入的類型中。高容錯(cuò)子進(jìn)程異常奔潰時(shí),主進(jìn)程將重建子進(jìn)程。高性能多進(jìn)程運(yùn)行,充分利用多個(gè)并行計(jì)算,性能強(qiáng)勁。 經(jīng)常在群里聽(tīng)到一些朋友問(wèn):TP 的項(xiàng)目怎么遷移到 mixphp 來(lái)處理高并發(fā),我通常都是回復(fù)需要重寫(xiě),可是一個(gè)開(kāi)發(fā)很久的 TP 項(xiàng)目,代碼量巨大,又怎么可能會(huì)花大量時(shí)間成本來(lái)重寫(xiě)呢? 那么為何我們不嘗試...
摘要:有三種狀態(tài)運(yùn)行關(guān)閉終止。類類,提供了一系列工廠方法用于創(chuàng)建線程池,返回的線程池都實(shí)現(xiàn)了接口。線程池的大小一旦達(dá)到最大值就會(huì)保持不變,在提交新任務(wù),任務(wù)將會(huì)進(jìn)入等待隊(duì)列中等待。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求。 這是java高并發(fā)系列第19篇文章。 本文主要內(nèi)容 介紹Executor框架相關(guān)內(nèi)容 介紹Executor 介紹ExecutorService 介紹線程池ThreadP...
摘要:線程的啟動(dòng)與銷毀都與本地線程同步。操作系統(tǒng)會(huì)調(diào)度所有線程并將它們分配給可用的??蚣艿某蓡T主要成員線程池接口接口接口以及工具類。創(chuàng)建單個(gè)線程的接口與其實(shí)現(xiàn)類用于表示異步計(jì)算的結(jié)果。參考書(shū)籍并發(fā)編程的藝術(shù)方騰飛魏鵬程曉明著 在java中,直接使用線程來(lái)異步的執(zhí)行任務(wù),線程的每次創(chuàng)建與銷毀需要一定的計(jì)算機(jī)資源開(kāi)銷。每個(gè)任務(wù)創(chuàng)建一個(gè)線程的話,當(dāng)任務(wù)數(shù)量多的時(shí)候,則對(duì)應(yīng)的創(chuàng)建銷毀開(kāi)銷會(huì)消耗大量...
摘要:新增新增模型方法,主動(dòng)刷新數(shù)據(jù)表結(jié)構(gòu)緩存。分布式并發(fā)模型是什么是一種與共享內(nèi)存對(duì)應(yīng)的并發(fā)模型,具有資源獨(dú)占性。都分布在不同的機(jī)器上。 One - 極簡(jiǎn) . 高性能 . 松耦合 . 分布式 . 可運(yùn)行于多種環(huán)境(cli,apache/php-fpm,swoole) 碼云: https://gitee.com/vicself/onegithub: https://github.com/li...
閱讀 3064·2023-04-26 02:27
閱讀 2776·2021-11-22 13:54
閱讀 916·2021-11-12 10:36
閱讀 3772·2021-10-09 09:44
閱讀 3188·2021-10-09 09:41
閱讀 1239·2021-09-22 10:02
閱讀 2848·2019-08-30 15:56
閱讀 3115·2019-08-30 11:02