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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程编程--异步转同步之CountDownLatch

發布時間:2024/2/28 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程编程--异步转同步之CountDownLatch 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自https://blog.csdn.net/vic_fang/article/details/24653477

————————————————————————————————————————————————————

?

在日常開發中,我們經常會碰到這樣的情況:一些異步請求我們需要等到接收到請求后再執行下一步動作,這時我們就需要把異步動作轉為同步動作。

?

java中給我們提供了一個CountDownLatch類來實現這個功能。

?

先看下CountDownLatch的官方定義:

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

意思是:CountDownLatch是一個同步助手,它可以使一個或多個線程等待,直到一系列在其他線程中執行的動作完成(這些線程才被喚醒)

?

具體如何使用呢?

看下這段文檔:

A?CountDownLatch?is initialized with a givencount. Theawait()?methods block until the current count reaches zero due to invocations of the countDown()?method, after which all waiting threads are released and any subsequent invocations ofawait()?return immediately.?

?

A useful property of aCountDownLatch?is that it doesn't require that threads callingcountDown?wait for the count to reach zero before proceeding, it simply prevents any thread from proceeding past anawait()?until all threads could pass.?

這句翻譯出來會有偏差,大家自己體會吧

?

詳細用例:

?

[java]?view plain?copy

  • class?Driver?{?//?...??????
  • ??void?main()?throws?InterruptedException?{??
  • ??????CountDownLatch?startSignal?=?new?CountDownLatch(1);??
  • ??????CountDownLatch?doneSignal?=?new?CountDownLatch(N);??
  • ????????
  • ??????for?(int?i?=?0;?i?<?N;?++i)?//?create?and?start?threads??
  • ????????new?Thread(new?Worker(startSignal,?doneSignal)).start();??
  • ????????
  • ??????doSomethingElse();????????????//?don't?let?run?yet??
  • ??????startSignal.countDown();??????//?let?all?threads?proceed??
  • ??????doSomethingElse();??
  • ??????doneSignal.await();???????????//?wait?for?all?to?finish??
  • ??}?????
  • ??class?Worker?implements?Runnable?{??
  • ????private?final?CountDownLatch?startSignal;??
  • ????private?final?CountDownLatch?doneSignal;??
  • ?????
  • ????Worker(CountDownLatch?startSignal,?CountDownLatch?doneSignal)?{??
  • ??????this.startSignal?=?startSignal;??
  • ??????this.doneSignal?=?doneSignal;??
  • ????}??
  • ??
  • ????????public?void?run()?{??
  • ??????try?{??
  • ????????startSignal.await();??
  • ????????doWork();??
  • ????????doneSignal.countDown();??
  • ??????}?catch?(InterruptedException?ex)?{}?//?return;??
  • ????}??
  • ???????
  • ????void?doWork()?{?...?}????
  • ??}??
  • }??
  • ?

    ?

    ?

    ——————————————————————-—————————————————————————————

    ?

    最近項目在執行過程中,有多個?獨立模塊?異步執行,將執行結果統一處理后返回,代碼可以順序調用各個模塊執行,然后統一處理,但是效率過低,考慮采用多線程異步處理,但異步執行提交任務后就順序執行其他代碼了,無法統一獲取各模塊處理結果。采用countDownLatch可以等待所有異步線程執行完成再統一處理。

    • countDownLatch jdk里描述?
      A synchronization aid that allows one or more threads to wait until?
      a set of operations being performed in other threads completes.?
      一個允許等待一個或多個其它線程執行完成的同步助手?
      使用場景:?
      1.等待一個或多個線程完成再執行其它操作?
      2.等待一個線程執行多次再執行其它操作?
    • countDownLatch實現原理
    private final Sync sync; public CountDownLatch(int count) {if (count < 0) throw new IllegalArgumentException("count < 0");this.sync = new Sync(count);} 初始化時將任務個數傳遞給同步控制器Sync,每次調用countDown方法,開始執行異步任務,Sync釋放一個資源 public void countDown() {sync.releaseShared(1);}調用await,await方法判斷Sycn的狀態,如果Sync狀態顯示未執行完成,則繼續分配資源執行。 當countDown為0時,統一返回異步結果。
    • 代碼示例
    import java.util.ArrayList; import java.util.List; import java.util.concurrent.*;public class MultiJobExecutors {private CountDownLatch countDownLatch;private List<Task> tasks;private static ExecutorService executor = null;public MultiJobExecutors(List<Task> tasks) {countDownLatch = new CountDownLatch(tasks.size());executor = Executors.newFixedThreadPool(tasks.size());this.tasks = tasks;}public void execute() {if (tasks == null|| tasks.isEmpty()) {return;}for (int i=0;i< tasks.size();i++) {executor.submit(new Job(countDownLatch,tasks.get(i)));System.out.println("xx"+i);}try {//等待所有線程結束countDownLatch.await(15, TimeUnit.SECONDS);//執行其他操作System.out.println("it's over");//關閉線程池executor.shutdown();} catch (InterruptedException e) {e.printStackTrace();}}private class Job implements Callable<Object>{private CountDownLatch latch;private Task task;public Job(CountDownLatch latch, Task task) {this.latch = latch;this.task = task;}@Overridepublic Object call() throws Exception {System.out.println(System.currentTimeMillis());//執行線程task.execute();//countDown自減latch.countDown();return null;}}private static class Task{private String str;public Task(String str) {this.str = str;}public void execute(){System.out.println(str);}}public static void main(String[] args) {Task task = new Task("I");Task task1 = new Task("love");Task task2 = new Task("you");Task task3 = new Task(",");Task task4 = new Task("its");Task task5 = new Task("not");Task task6 = new Task("true");List<Task> tasks = new ArrayList<Task>();tasks.add(task);tasks.add(task1);tasks.add(task2);tasks.add(task3);tasks.add(task4);tasks.add(task5);tasks.add(task6);MultiJobExecutors multiJobExecutors = new MultiJobExecutors(tasks);multiJobExecutors.execute();} }
    • 執行結果
    xx0 1472706027197 I xx1 1472706027197 love xx2 1472706027197 you xx3 1472706027197 , xx4 1472706027197 its xx5 1472706027198 not xx6 1472706027198 true it's over

    CountDownLatch的概念

    CountDownLatch是一個同步工具類,用來協調多個線程之間的同步,或者說起到線程之間的通信(而不是用作互斥的作用)。

    CountDownLatch能夠使一個線程在等待另外一些線程完成各自工作之后,再繼續執行。使用一個計數器進行實現。計數器初始值為線程的數量。當每一個線程完成自己任務后,計數器的值就會減一。當計數器的值為0時,表示所有的線程都已經完成了任務,然后在CountDownLatch上等待的線程就可以恢復執行任務。

    CountDownLatch的用法

    CountDownLatch典型用法1:某一線程在開始運行前等待n個線程執行完畢。將CountDownLatch的計數器初始化為n?new CountDownLatch(n)?,每當一個任務線程執行完畢,就將計數器減1?countdownlatch.countDown(),當計數器的值變為0時,在CountDownLatch上?await()?的線程就會被喚醒。一個典型應用場景就是啟動一個服務時,主線程需要等待多個組件加載完畢,之后再繼續執行。

    CountDownLatch典型用法2:實現多個線程開始執行任務的最大并行性。注意是并行性,不是并發,強調的是多個線程在某一時刻同時開始執行。類似于賽跑,將多個線程放到起點,等待發令槍響,然后同時開跑。做法是初始化一個共享的CountDownLatch(1),將其計數器初始化為1,多個線程在開始執行任務前首先?coundownlatch.await(),當主線程調用?countDown()?時,計數器變為0,多個線程同時被喚醒。

    CountDownLatch的不足

    CountDownLatch是一次性的,計數器的值只能在構造方法中初始化一次,之后沒有任何機制再次對其設置值,當CountDownLatch使用完畢后,它不能再次被使用。

    參考資料:http://www.importnew.com/15731.html

    ?

    ?

    總結

    以上是生活随笔為你收集整理的多线程编程--异步转同步之CountDownLatch的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。