Java并發(fā)編程之CountDownLatch解讀
概念
- countDownLatch這個類使一個線程等待其他線程各自執(zhí)行完畢后再執(zhí)行。
- 是通過一個計數(shù)器來實現(xiàn)的,計數(shù)器的初始值是線程的數(shù)量。每當一個線程執(zhí)行完畢后,計數(shù)器的值就-1,當計數(shù)器的值為0時,表示所有線程都執(zhí)行完畢,然后在閉鎖上等待的線程就可以恢復工作了。
源碼
countDownLatch類中只提供了一個構造器:
//參數(shù)count為計數(shù)值 public CountDownLatch(int count) { };
類中有三個方法是最重要的:
//調(diào)用await()方法的線程會被掛起,它會等待直到count值為0才繼續(xù)執(zhí)行 public void await() throws InterruptedException { }; //和await()類似,只不過等待一定的時間后count值還沒變?yōu)?的話就會繼續(xù)執(zhí)行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { }; //將count值減1 public void countDown() { };
自定義實現(xiàn)一個CountDownLatch
代碼如下:
public class KaneCountDownLatch { private KaneCountDownLatch.Sync sync; public KaneCountDownLatch(int count) { this.sync = new KaneCountDownLatch.Sync(count); } public void countDown() { this.sync.releaseShared(1); } public void await() { this.sync.acquireShared(1); } class Sync extends AbstractQueuedSynchronizer { public Sync(int count) { this.setState(count); } protected int tryAcquireShared(int arg) { return this.getState() == 0 ? 1 : -1; } protected boolean tryReleaseShared(int arg) { int c; int nextc; do { c = this.getState(); if (c == 0) { return false; } nextc = c - 1; } while(!this.compareAndSetState(c, nextc)); return nextc == 0; } } }
測試代碼如下:
public class CountDownLatch_Demo { public static void main(String[] args) throws InterruptedException { KaneCountDownLatch latch = new KaneCountDownLatch(6); //計數(shù)為6 for (int i = 0; i <6 ; i++) { new Thread(()->{ System.out.println("開始準備....."); latch.countDown();//計數(shù)減一 }).start(); Thread.sleep(1000); } latch.await(); //每個線程執(zhí)行一次,則-1,在latch為0的時候開始向下運行 這是這些線程都準備就緒,然后去一起干同一件事 //還有一種方式, 將一個活分為多段,每個線程去干一段 // for (int i = 0; i <6 ; i++) { // new Thread(()->{ // latch.countDown(); // 計數(shù)減一 // try { // latch.await(); // 阻塞 -- > 0 // System.out.println("線程:"+Thread.currentThread().getName()+"執(zhí)行完畢"); // } catch (InterruptedException e) { // e.printStackTrace(); // } // }).start(); // } System.out.println("開始干活...."); } }
CountDownLatch和CyclicBarrier區(qū)別
- countDownLatch是一個計數(shù)器,線程完成一個記錄一個,計數(shù)器遞減,只能只用一次
- CyclicBarrier的計數(shù)器更像一個閥門,需要所有線程都到達,然后繼續(xù)執(zhí)行,計數(shù)器遞增,提供reset功能,可以多次使用
到此這篇關于Java并發(fā)編程之CountDownLatch解讀的文章就介紹到這了,更多相關CountDownLatch解讀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring項目如何實現(xiàn)帶請求鏈路id的日志記錄
我們在做項目的時候通常需要通過請求日志來排查定位線上問題,如果日志比較多而我們又需要查找整個請求的全部日志的時候會比較困難,下面我們就來看看如何用java aop實現(xiàn)請求id的日志記錄吧2024-12-12Shiro整合Springboot和redis,jwt過程中的錯誤shiroFilterChainDefinition問
這篇文章主要介紹了Shiro整合Springboot和redis,jwt過程中的錯誤shiroFilterChainDefinition問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04Java內(nèi)存之happens-before和重排序
在JMM(Java內(nèi)存模型)中,如果一個操作執(zhí)行的結果需要對另一個操作可見,那么這兩個操作之間必須存在happens-before關系。下面小編來簡單介紹一下2019-05-05Springboot?集成spring?cache緩存的解決方案
這篇文章主要介紹了Springboot?集成spring?cache緩存,使用緩存最關鍵的一點就是保證緩存與數(shù)據(jù)庫的數(shù)據(jù)一致性,本文給大家介紹最常用的緩存操作模式,對Springboot?集成spring?cache緩存操作流程感興趣的朋友一起看看吧2022-06-06Hibernate一對多關聯(lián)雙向關聯(lián)代碼實現(xiàn)分享
Hibernate一對多關聯(lián)雙向關聯(lián)代碼實現(xiàn)分享,大家參考使用吧2013-12-12MyBatis?如何使項目兼容多種數(shù)據(jù)庫的解決方案
要想做兼容多種數(shù)據(jù)庫,那毫無疑問,我們首先得明確我們要兼容哪些數(shù)據(jù)庫,他們的數(shù)據(jù)庫產(chǎn)品名稱是什么,本次我們講解了一套使項目兼容多種數(shù)據(jù)庫的方案,對MyBatis項目兼容多種數(shù)據(jù)庫操作方法感興趣的朋友一起看看吧2024-05-05