您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“JUC CountDownLach原理是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“JUC CountDownLach原理是什么”吧!
CountDownLach閉鎖
背景
CountDownLatch是在Java1.5被引入,跟它一起被引入的工具類還有CyclicBarrier、Semaphore、ConcurrenthashMap和BlockingQueue。
在java.util.cucurrent包下。
概念
CountDownLatch這個(gè)類使一個(gè)線程等待其它線程各自執(zhí)行完畢后再執(zhí)行。
是通過(guò)一個(gè)計(jì)數(shù)器來(lái)實(shí)現(xiàn)的,計(jì)數(shù)器的初始值是線程的數(shù)量。每當(dāng)一個(gè)線程執(zhí)行完畢后,計(jì)數(shù)器的值就-1,當(dāng)計(jì)數(shù)器的值為0時(shí),表示所有線程都執(zhí)行完畢,然后在閉鎖上等待的線程就可以恢復(fù)工作來(lái)。
源碼
countDownLatch類中只提供了一個(gè)構(gòu)造器
public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); }
類中有三個(gè)方法是最重要的
// 調(diào)用await()方法的線程會(huì)被掛起,它會(huì)等待直到count值為0才繼續(xù)執(zhí)行 public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); }//和await()方法類似,只不過(guò)等待一定的時(shí)間后count值還沒(méi)變?yōu)?的化就會(huì)繼續(xù)執(zhí)行 public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); }//將count值減1 public void countDown() { sync.releaseShared(1); }
示例
普通示例:
public class CountDownLatchTest { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); System.out.println("主線程開(kāi)始執(zhí)行…… ……"); //第一個(gè)子線程執(zhí)行 ExecutorService es1 = Executors.newSingleThreadExecutor(); es1.execute(new Runnable() { @Override public void run() { try { Thread.sleep(3000); System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); } catch (InterruptedException e) { e.printStackTrace(); } latch.countDown(); } }); es1.shutdown(); //第二個(gè)子線程執(zhí)行 ExecutorService es2 = Executors.newSingleThreadExecutor(); es2.execute(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子線程:"+Thread.currentThread().getName()+"執(zhí)行"); latch.countDown(); } }); es2.shutdown(); System.out.println("等待兩個(gè)線程執(zhí)行完畢…… ……"); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程"); } }
結(jié)果集:
主線程開(kāi)始執(zhí)行…… …… 等待兩個(gè)線程執(zhí)行完畢…… ……子線程:pool-1-thread-1執(zhí)行子線程:pool-2-thread-1執(zhí)行兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程
模擬并發(fā)示例:
public class Parallellimit { public static void main(String[] args) { ExecutorService pool = Executors.newCachedThreadPool(); CountDownLatch cdl = new CountDownLatch(100); for (int i = 0; i < 100; i++) { CountRunnable runnable = new CountRunnable(cdl); pool.execute(runnable); } }} class CountRunnable implements Runnable { private CountDownLatch countDownLatch; public CountRunnable(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { try { synchronized (countDownLatch) { /*** 每次減少一個(gè)容量*/ countDownLatch.countDown(); System.out.println("thread counts = " + (countDownLatch.getCount())); } countDownLatch.await(); System.out.println("concurrency counts = " + (100 - countDownLatch.getCount())); } catch (InterruptedException e) { e.printStackTrace(); } }}
源碼分析
public class CountDownLatch { //繼承AQS來(lái)實(shí)現(xiàn)他的模板方法(tryAcquireShared,tryReleaseShared) private static final class Sync extends AbstractQueuedSynchronizer { //計(jì)數(shù)個(gè)數(shù)Count Sync(int count) { setState(count); } int getCount() { return getState(); } //AQS方法getState(),返回同步狀態(tài),這里指計(jì)數(shù)器值 protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } //循環(huán)+cas重試 直到計(jì)數(shù)器為0 跳出,則release(實(shí)現(xiàn)aqs共享模式釋放方法) protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } } } private final Sync sync; //實(shí)例化 public CountDownLatch(int count) { if (count < 0) throw new IllegalArgumentException("count < 0"); this.sync = new Sync(count); } public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } //帶有一個(gè)超時(shí)時(shí)間的awit public boolean await(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } public void countDown() { sync.releaseShared(1); } public long getCount() { return sync.getCount(); }}
到此,相信大家對(duì)“JUC CountDownLach原理是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。