日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java并发编程--CountDownLatch

發(fā)布時(shí)間:2024/10/12 java 67 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java并发编程--CountDownLatch 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

概述

  CountDownLatch是一個(gè)同步工具類(lèi),它允許一個(gè)或多個(gè)線(xiàn)程一直等待,直到其他線(xiàn)程的操作執(zhí)行完后再執(zhí)行。

  CountDownLatch使用一個(gè)計(jì)數(shù)器count實(shí)現(xiàn),構(gòu)建CountDownLatch時(shí)需要使用給定的count初始化CountDownLatch。在count到達(dá)0之前,調(diào)用await()方法的線(xiàn)程將一直阻塞,當(dāng)count到達(dá)0時(shí),會(huì)喚醒所有阻塞的線(xiàn)程。注意:計(jì)數(shù)器count無(wú)法被重置,即只能實(shí)現(xiàn)一次這種功能,這也是CountDownLatch與CyclicBarrier的區(qū)別。

  內(nèi)存一致性效果:線(xiàn)程中調(diào)用 countDown() 之前的操作 happen-before 緊跟在從另一個(gè)線(xiàn)程中對(duì)應(yīng) await() 成功返回的操作。?

使用

  CountDownLatch 是一個(gè)通用同步工具,它有很多用途。將計(jì)數(shù) 1 初始化的 CountDownLatch 用作一個(gè)簡(jiǎn)單的開(kāi)/關(guān)鎖存器,或入口:在通過(guò)調(diào)用 countDown() 的線(xiàn)程打開(kāi)入口前,所有調(diào)用 await 的線(xiàn)程都一直在入口處等待。用 N 初始化的 CountDownLatch 可以使一個(gè)線(xiàn)程在 N 個(gè)線(xiàn)程完成某項(xiàng)操作之前一直等待,或者使其在某項(xiàng)操作完成 N 次之前一直等待。

  提供的方法:

1 //使當(dāng)前線(xiàn)程阻塞直到計(jì)數(shù)器count變?yōu)?,除非被中斷 2 public void await() throws InterruptedException 3 //使當(dāng)前線(xiàn)程阻塞直到計(jì)數(shù)器count變?yōu)?,除非被中斷或超過(guò)了指定時(shí)間 4 public boolean await(long timeout, TimeUnit unit) throws InterruptedException 5 //將計(jì)數(shù)器count遞減,若count變?yōu)?則喚醒所有等待的線(xiàn)程 6 public void countDown() 7 //返回計(jì)數(shù)器count值 8 public long getCount()

  使用示例:Driver主線(xiàn)程中控制N個(gè)Worker線(xiàn)程的啟動(dòng),并等待所有Worker線(xiàn)程完成再退出。

1 class Driver { // ... 2 void main() throws InterruptedException { 3 CountDownLatch startSignal = new CountDownLatch(1); //啟動(dòng)信號(hào) 4 CountDownLatch doneSignal = new CountDownLatch(N); //完成信號(hào) 5 6 for (int i = 0; i < N; ++i) // create and start threads 7 new Thread(new Worker(startSignal, doneSignal)).start(); 8 9 doSomethingElse(); // don't let run yet 10 //將啟動(dòng)信號(hào)的計(jì)數(shù)器置為0,啟動(dòng)等待的Worker線(xiàn)程 11 startSignal.countDown(); // let all threads proceed 12 doSomethingElse(); 13 //等待N個(gè)Worker線(xiàn)程完成 14 doneSignal.await(); // wait for all to finish 15 } 16 } 17 18 class Worker implements Runnable { 19 private final CountDownLatch startSignal; 20 private final CountDownLatch doneSignal; 21 Worker(CountDownLatch startSignal, CountDownLatch doneSignal) { 22 this.startSignal = startSignal; 23 this.doneSignal = doneSignal; 24 } 25 public void run() { 26 try { 27 startSignal.await(); //等待啟動(dòng)信號(hào) 28 doWork(); 29 doneSignal.countDown(); //發(fā)出完成信號(hào),將完成信號(hào)的計(jì)數(shù)器減1 30 } catch (InterruptedException ex) {} // return; 31 } 32 33 void doWork() { ... } 34 }

?

實(shí)現(xiàn)原理

  CountDownLatch基于AQS實(shí)現(xiàn),使用AQS的同步狀態(tài)state表示計(jì)數(shù)器count。

  先看一下CountDownLatch的內(nèi)部類(lèi)Syns的實(shí)現(xiàn):

1 private static final class Sync extends AbstractQueuedSynchronizer { 2 private static final long serialVersionUID = 4982264981922014374L; 3 4 Sync(int count) { 5 setState(count); //設(shè)置同步狀態(tài)state為count 6 } 7 8 int getCount() { 9 return getState(); //查詢(xún)同步狀態(tài) 10 } 11 //重寫(xiě)AQS的共享式獲取同步狀態(tài)的方法。當(dāng)state=0時(shí)返回1,獲取成功;當(dāng)state=1時(shí)返回-1,獲取失敗。 12 protected int tryAcquireShared(int acquires) { 13 return (getState() == 0) ? 1 : -1; 14 } 15 //重寫(xiě)AQS的共享式釋放同步狀態(tài)的方法。基于自旋CAS遞減同步狀態(tài) 16 protected boolean tryReleaseShared(int releases) { 17 // Decrement count; signal when transition to zero 18 //如果state=0,那么直接返回false 19 //如果state>0,那么遞減state。若更新后的state=0則返回true,釋放同步狀態(tài)成功;反之,返回false。 20 for (;;) { 21 int c = getState(); 22 if (c == 0) 23 return false; 24 int nextc = c-1; 25 if (compareAndSetState(c, nextc)) 26 return nextc == 0; 27 } 28 } 29 }

    由Sync源碼可以看出,CountDownLatch基于AQS的共享式獲取和釋放同步狀態(tài)的機(jī)制實(shí)現(xiàn)。

  await()

1 //調(diào)用AQS提供的共享式可中斷獲取同步狀態(tài)方法。 2 //若獲取成功(state=0),繼續(xù)執(zhí)行后續(xù)代碼;否則(state>0),阻塞當(dāng)前線(xiàn)程。 3 public void await() throws InterruptedException { 4 sync.acquireSharedInterruptibly(1); 5 }

?

  countDown()

1 //調(diào)用AQS提供的共享式釋放同步狀態(tài)方法。 2 //若釋放成功(tryReleaseShared返回true),喚醒同步隊(duì)列上的后繼節(jié)點(diǎn);若釋放失敗(tryReleaseShared返回false),不做任何操作。 3 public void countDown() { 4 sync.releaseShared(1); 5 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/zaizhoumo/p/7786893.html

總結(jié)

以上是生活随笔為你收集整理的Java并发编程--CountDownLatch的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。