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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java的几个同步辅助类

發布時間:2023/12/20 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java的几个同步辅助类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java為我們提供了一些同步輔助類,利用這些輔助類我們可以在多線程編程中,靈活地把握線程的狀態。

CountDownLatch

CountDownLatch一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待。

再CountDownLatch中兩個比較關鍵的方法:

public void await() throws InterruptedException; public void countDown();

CountDownLatch是一個計數器,它的構造方法中需要設置一個數值,用來設定計數的次數。每次調用countDown()方法之后,這個計數器都會減去1,CountDownLatch會一直阻塞著調用await()方法的線程,直到計數器的值變為0。

設想有這樣一個功能需要Thread1、Thread2、Thread3、Thread4四條線程分別統計C、D、E、F四個盤的大小,所有線程都統計完畢交給主線程去做匯總,利用CountDownLatch來完成就非常輕松。

public class CountDownLatchTest {private static CountDownLatch count = new CountDownLatch(4);private static ExecutorService service = Executors.newFixedThreadPool(6);public static void main(String args[]) throws InterruptedException {for (int i = 0; i < 4; i++) {service.execute(() -> {// 模擬任務耗時try {int timer = new Random().nextInt(5);TimeUnit.SECONDS.sleep(timer);System.out.printf("%s時完成磁盤的統計任務,耗費%d秒.\n", new Date().toString(), timer);// 任務完成之后,計數器減一count.countDown();} catch (InterruptedException e) {e.printStackTrace();}});}// 主線程一直被阻塞,知道count的計數器被設置為0count.await();System.out.printf("%s時全部任務都完成,執行合并計算.\n", new Date().toString());service.shutdown();} }

CyclicBarrier

Barrier在英語中是屏障的意思,這個同步工具會阻塞調用的線程,直到條件滿足時,阻塞的線程同時被打開。

public int await() throws InterruptedException, BrokenBarrierException

CyclicBarrier初始化的時候,設置一個屏障數。線程調用await()方法的時候,這個線程就會被阻塞,當調用await()的線程數量到達屏障數的時候,主線程就會取消所有被阻塞線程的狀態。

在CyclicBarrier的構造方法中,還可以設置一個barrierAction。

在所有的屏障都到達之后,會啟動一個線程來運行這里面的代碼。這里舉一個例子:百米賽跑的運動員起跑前需要準備,所有選手準備完畢之后,才可以同時起跑。

public class CyclicBarrierTest {private static CyclicBarrier cyclicBarrier = new CyclicBarrier(8);private static ExecutorService service = Executors.newFixedThreadPool(50);public static void main(String args[]) {for (int i = 1; i < 9; i++) {service.execute(new Thread(new Runner(i, cyclicBarrier)));}service.shutdown();} } // 運動員類 public class Runner implements Runnable {private int number;private CyclicBarrier cyclicBarrier;public Runner(int number, CyclicBarrier cyclicBarrier) {this.number = number;this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {try {int timer = new Random().nextInt(5);TimeUnit.SECONDS.sleep(timer);System.out.printf("%d號選手準備完畢,準備時間%d\n", number, timer);cyclicBarrier.await();System.out.printf("%d號選手于%s時起跑!\n", number, new Date().toString());} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}} }

輸出:

1號選手準備完畢,準備時間0 4號選手準備完畢,準備時間0 5號選手準備完畢,準備時間1 8號選手準備完畢,準備時間1 3號選手準備完畢,準備時間2 2號選手準備完畢,準備時間3 7號選手準備完畢,準備時間3 6號選手準備完畢,準備時間3 7號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 2號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 5號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 6號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 3號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 8號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 4號選手于Sun Mar 27 21:19:00 CST 2016時起跑! 1號選手于Sun Mar 27 21:19:00 CST 2016時起跑!

相比CountDownLatch,CyclicBarrier是可以被循環使用的,而且遇到線程中斷等情況時,還可以利用reset()方法,重置計數器,從這些方面來說,CyclicBarrier會比CountDownLatch更加靈活一些。

Semaphore

Semaphore被用于控制特定資源在同一個時間被訪問的個數。類似連接池的概念,保證資源可以被合理的使用。

Semaphore的幾個重要方法:

// 獲取資源 public void acquire() throws InterruptedException // 釋放資源 public void release()

Semaphore的構造方法可以設置一個int值來設置一個計數器,用于表示資源同時可以被多少外部環境使用。每使用一次acquire(),計數器都會去減去一,而每次調用release()計數器則會增加一。當計數器的值為0的時候,外部的環境被阻塞,直到Semaphore有空閑的資源可以被使用。

public class SemaphoreTest {private static Semaphore semaphore = new Semaphore(3);private static ExecutorService service = Executors.newFixedThreadPool(6);public static void main(String args[]) {// 執行9個任務for (int i = 0; i < 9; i++) {service.execute(() -> {try {semaphore.acquire();System.out.printf("%s時獲取資源,并調用.\n", new Date().toString());// 線程掛起3秒TimeUnit.SECONDS.sleep(3);semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}});}service.shutdown();} }

運行的結果就是:

Sun Mar 27 20:18:16 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:16 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:16 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:19 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:19 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:19 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:22 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:22 CST 2016時獲取資源,并調用. Sun Mar 27 20:18:22 CST 2016時獲取資源,并調用.

雖然線程池允許6個最大線程數量,但是同一個時間內只用三個任務被執行。

轉載于:https://www.cnblogs.com/whthomas/p/java_concurrent_tools.html

總結

以上是生活随笔為你收集整理的Java的几个同步辅助类的全部內容,希望文章能夠幫你解決所遇到的問題。

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