溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JUC CountDownLach原理是什么

發(fā)布時(shí)間:2021-10-26 15:41:49 來(lái)源:億速云 閱讀:139 作者:iii 欄目:編程語(yǔ)言

本篇內(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í)行&hellip;&hellip; &hellip;&hellip;");         //第一個(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í)行完畢&hellip;&hellip; &hellip;&hellip;");         try {             latch.await();         } catch (InterruptedException e) {             e.printStackTrace();         }         System.out.println("兩個(gè)子線程都執(zhí)行完畢,繼續(xù)執(zhí)行主線程");     } }

結(jié)果集:

主線程開(kāi)始執(zhí)行&hellip;&hellip; &hellip;&hellip; 等待兩個(gè)線程執(zhí)行完畢&hellip;&hellip; &hellip;&hellip;子線程: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í)!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI