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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

java多线程学习-java.util.concurrent详解(一) Latch/Barrier

發布時間:2023/12/10 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

??? Java1.5提供了一個非常高效實用的多線程包:java.util.concurrent, 提供了大量高級工具,可以幫助開發者編寫高效、易維護、結構清晰的Java多線程程序。從這篇blog起,我將跟大家一起共同學習這些新的Java多線程構件

1. CountDownLatch
??? 我們先來學習一下JDK1.5 API中關于這個類的詳細介紹:
“一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。 用給定的計數 初始化 CountDownLatch。由于調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之后,會釋放所有等待的線程,await 的所有后續調用都將立即返回。這種現象只出現一次——計數無法被重置。如果需要重置計數,請考慮使用 CyclicBarrier?!?

??? 這就是說,CountDownLatch可以用來管理一組相關的線程執行,只需在主線程中調用CountDownLatch 的await方法(一直阻塞),讓各個線程調用countDown方法。當所有的線程都只需完countDown了,await也順利返回,不再阻塞了。在這樣情況下尤其適用:將一個任務分成若干線程執行,等到所有線程執行完,再進行匯總處理。

??? 下面我舉一個非常簡單的例子。 假設我們要打印1-100,最后再輸出“Ok“。1-100的打印順序不要求統一,只需保證“Ok“是在最后出現即可。

??? 解決方案:我們定義一個CountDownLatch,然后開10個線程分別打印(n-1)*10+1至(n-1)*10+10。主線程中調用await方法等待所有線程的執行完畢,每個線程執行完畢后都調用countDown方法。最后再await返回后打印“Ok”。

具體代碼如下(本代碼參考了JDK示例代碼):
import java.util.concurrent.CountDownLatch; /*** 示例:CountDownLatch的使用舉例* Mail: ken@iamcoding.com* @author janeky*/ public class TestCountDownLatch {private static final int N = 10;public static void main(String[] args) throws InterruptedException {CountDownLatch doneSignal = new CountDownLatch(N);CountDownLatch startSignal = new CountDownLatch(1);//開始執行信號for (int i = 1; i <= N; i++) {new Thread(new Worker(i, doneSignal, startSignal)).start();//線程啟動了}System.out.println("begin------------");startSignal.countDown();//開始執行啦doneSignal.await();//等待所有的線程執行完畢System.out.println("Ok");}static class Worker implements Runnable {private final CountDownLatch doneSignal;private final CountDownLatch startSignal;private int beginIndex;Worker(int beginIndex, CountDownLatch doneSignal,CountDownLatch startSignal) {this.startSignal = startSignal;this.beginIndex = beginIndex;this.doneSignal = doneSignal;}public void run() {try {startSignal.await(); //等待開始執行信號的發布beginIndex = (beginIndex - 1) * 10 + 1;for (int i = beginIndex; i <= beginIndex + 10; i++) {System.out.println(i);}} catch (InterruptedException e) {e.printStackTrace();} finally {doneSignal.countDown();}}} }

??? 總結:CounDownLatch對于管理一組相關線程非常有用。上述示例代碼中就形象地描述了兩種使用情況。第一種是計算器為1,代表了兩種狀態,開關。第二種是計數器為N,代表等待N個操作完成。今后我們在編寫多線程程序時,可以使用這個構件來管理一組獨立線程的執行。

2. CyclicBarrier
??? 我們先來學習一下JDK1.5 API中關于這個類的詳細介紹:
??? “一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點 (common barrier point)。在涉及一組固定大小的線程的程序中,這些線程必須不時地互相等待,此時 CyclicBarrier 很有用。因為該 barrier 在釋放等待線程后可以重用,所以稱它為循環 的 barrier。
??? CyclicBarrier 支持一個可選的 Runnable 命令,在一組線程中的最后一個線程到達之后(但在釋放所有線程之前),該命令只在每個屏障點運行一次。若在繼續所有參與線程之前更新共享狀態,此屏障操作 很有用。

??? 我們在學習CountDownLatch的時候就提到了CyclicBarrier。兩者究竟有什么聯系呢?引用[JCIP]中的描述“The key difference is that with a barrier, all the threads must come together at a barrier point at the same time in order to proceed. Latches are for waiting for events; barriers are for waiting for other threads。CyclicBarrier等待所有的線程一起完成后再執行某個動作。這個功能CountDownLatch也同樣可以實現。但是CountDownLatch更多時候是在等待某個事件的發生。在CyclicBarrier中,所有的線程調用await方法,等待其他線程都執行完。

??? 舉一個很簡單的例子, 今天晚上我們哥們4個去Happy。就互相通知了一下:晚上八點準時到xx酒吧門前集合,不見不散!。有個哥們住的近,早早就到了。有的事務繁忙,剛好踩點到了。無論怎樣,先來的都不能獨自行動,只能等待所有人

代碼如下(參考了網上給的一些教程)
import java.util.Random; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class TestCyclicBarrier {public static void main(String[] args) {ExecutorService exec = Executors.newCachedThreadPool(); final Random random=new Random();final CyclicBarrier barrier=new CyclicBarrier(4,new Runnable(){@Overridepublic void run() {System.out.println("大家都到齊了,開始happy去");}});for(int i=0;i<4;i++){exec.execute(new Runnable(){@Overridepublic void run() {try {Thread.sleep(random.nextInt(1000));} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"到了,其他哥們呢");try {barrier.await();//等待其他哥們} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}});}exec.shutdown();}}

??? 關于await方法要特別注意一下,它有可能在阻塞的過程中由于某些原因被中斷

??? 總結:CyclicBarrier就是一個柵欄,等待所有線程到達后再執行相關的操作。barrier 在釋放等待線程后可以重用。

更多的Java編程資料,歡迎訪問我的blog: http://janeky.iteye.com,希望能夠與你有更多的交流

未完待續

轉載于:https://my.oschina.net/kkrgwbj/blog/398271

總結

以上是生活随笔為你收集整理的java多线程学习-java.util.concurrent详解(一) Latch/Barrier的全部內容,希望文章能夠幫你解決所遇到的問題。

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