Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解
CountDownLatch
CountDownLatch
是一個同步輔助類,它允許一個或多個線程等待,直到其他線程完成一組操作。CountDownLatch
有一個計數(shù)器,當計數(shù)器減為0時,等待的線程將被喚醒。計數(shù)器只能減少,不能增加。
示例:使用CountDownLatch等待所有線程完成任務
假設我們有一個任務需要三個子任務完成,我們可以使用CountDownLatch
來等待所有子任務完成。
import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " started"); try { Thread.sleep(1000 * taskNumber); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Task " + taskNumber + " completed"); latch.countDown(); }).start(); } System.out.println("Waiting for all tasks to complete..."); latch.await(); System.out.println("All tasks completed"); } }
在這個示例中,我們創(chuàng)建了一個CountDownLatch
并設置初始計數(shù)器為3。每個子任務完成后,調用latch.countDown()
減少計數(shù)器。主線程調用latch.await()
等待所有子任務完成。
CyclicBarrier
CyclicBarrier
是一個同步輔助類,它允許一組線程相互等待,直到所有線程都準備好繼續(xù)執(zhí)行。當所有線程都到達屏障點時,屏障將打開。CyclicBarrier
可以重復使用。
示例:使用CyclicBarrier同步多個線程
假設我們有三個線程需要在某個點同步,我們可以使用CyclicBarrier
實現(xiàn)這個目的。
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class CyclicBarrierExample { public static void main(String[] args) { CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All threads are ready to proceed")); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " is ready"); try { barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println("Task " + taskNumber + " is proceeding"); }).start(); } } }
在這個示例中,我們創(chuàng)建了一個CyclicBarrier
并設置參與者數(shù)量為3。每個線程在準備好繼續(xù)執(zhí)行之前調用barrier.await()
。當所有線程都準備好時,屏障將打開,所有線程將繼續(xù)執(zhí)行。
Semaphore
Semaphore
是一個計數(shù)信號量,它維護了一個許可集。線程可以請求許可,如果有可用的許可,線程將獲得許可并繼續(xù)執(zhí)行。否則,線程將阻塞,直到有可用的許可。許可可以由任何線程釋放。Semaphore
可用于實現(xiàn)資源池、限制并發(fā)訪問等。
示例:使用Semaphore限制并發(fā)訪問
假設我們有一個只能同時處理三個請求的服務器,我們可以使用Semaphore
來實現(xiàn)并發(fā)訪問限制。
import java.util.concurrent.Semaphore; public class SemaphoreExample { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 10; i++) final int clientNumber = i; new Thread(() -> { try { System.out.println("Client " + clientNumber + " is trying to connect"); semaphore.acquire(); System.out.println("Client " + clientNumber + " is connected"); Thread.sleep(2000); System.out.println("Client " + clientNumber + " is disconnected"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } }).start(); } } }
在這個示例中,我們創(chuàng)建了一個Semaphore
并設置初始許可數(shù)量為3。每個客戶端線程在連接服務器之前調用semaphore.acquire()
請求許可。當許可可用時,線程將獲得許可并繼續(xù)執(zhí)行。線程完成后,調用semaphore.release()
釋放許可。
Exchanger
Exchanger
是一個同步輔助類,它允許兩個線程在一個臨界點交換數(shù)據(jù)。當兩個線程都到達交換點時,它們將交換數(shù)據(jù)。Exchanger
可以用于遺傳算法、管道設計等。
示例:使用Exchanger交換數(shù)據(jù)
假設我們有兩個線程,一個生成數(shù)據(jù),另一個處理數(shù)據(jù)。我們可以使用Exchanger
在這兩個線程之間交換數(shù)據(jù)。
import java.util.concurrent.Exchanger; public class ExchangerExample { public static void main(String[] args) { Exchanger<String> exchanger = new Exchanger<>(); new Thread(() -> { try { String data = "Data from producer"; System.out.println("Producer is sending: " + data); String receivedData = exchanger.exchange(data); System.out.println("Producer received: " + receivedData); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { String data = "Data from consumer"; System.out.println("Consumer is sending: " + data); String receivedData = exchanger.exchange(data); System.out.println("Consumer received: " + receivedData); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } }
在這個示例中,我們創(chuàng)建了一個Exchanger
。生產(chǎn)者和消費者線程在交換數(shù)據(jù)前調用exchanger.exchange(data)
。當兩個線程都到達交換點時,它們將交換數(shù)據(jù)。
Phaser
Phaser
是一個靈活的同步輔助類,它允許一組線程相互等待,直到所有線程都準備好繼續(xù)執(zhí)行。與CyclicBarrier
類似,但Phaser
更加靈活,可以動態(tài)調整參與者數(shù)量和支持多個階段。
示例:使用Phaser同步多個線程
假設我們有三個線程需要在某個點同步,我們可以使用Phaser
實現(xiàn)這個目的。
import java.util.concurrent.Phaser; public class PhaserExample { public static void main(String[] args) { Phaser phaser = new Phaser(3); for (int i = 1; i <= 3; i++) { final int taskNumber = i; new Thread(() -> { System.out.println("Task " + taskNumber + " is ready"); phaser.arriveAndAwaitAdvance(); System.out.println("Task " + taskNumber + " is proceeding"); }).start(); } } }
在這個示例中,我們創(chuàng)建了一個Phaser
并設置參與者數(shù)量為3。每個線程在準備好繼續(xù)執(zhí)行之前調用phaser.arriveAndAwaitAdvance()
。當所有線程都準備好時,屏障將打開,所有線程將繼續(xù)執(zhí)行。
這些并發(fā)工具類為Java多線程編程提供了強大的支持,幫助我們更輕松地實現(xiàn)各種同步和并發(fā)場景。希望這些示例能幫助你理解并掌握這些工具類的用法。
以上就是Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解的詳細內容,更多關于Java并發(fā)工具類的資料請關注腳本之家其它相關文章!
相關文章
SpringBoot可視化接口開發(fā)工具magic-api的簡單使用教程
作為Java后端開發(fā),平時開發(fā)API接口的時候經(jīng)常需要定義Controller、Service、Dao、Mapper、XML、VO等Java對象。有沒有什么辦法可以讓我們不寫這些代碼,直接操作數(shù)據(jù)庫生成API接口呢?今天給大家推薦一款工具magic-api,來幫我們實現(xiàn)這個小目標!2021-06-06Java實現(xiàn)的獲取和判斷文件頭信息工具類用法示例
這篇文章主要介紹了Java實現(xiàn)的獲取和判斷文件頭信息工具類,結合實例形式分析了Java針對文件讀取及頭信息判斷相關操作技巧,需要的朋友可以參考下2017-11-11Oracle + Mybatis實現(xiàn)批量插入、更新和刪除示例代碼
利用MyBatis動態(tài)SQL的特性,我們可以做一些批量的操作,下面這篇文章主要給大家介紹了關于Oracle + Mybatis實現(xiàn)批量插入、更新和刪除的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。2018-01-01Mybatis實現(xiàn)Mapper動態(tài)代理方式詳解
這篇文章主要為大家詳細介紹了Mybatis實現(xiàn)Mapper動態(tài)代理方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08SpringMVC中的HandlerMapping和HandlerAdapter詳解
這篇文章主要介紹了SpringMVC中的HandlerMapping和HandlerAdapter詳解,在Spring MVC中,HandlerMapping(處理器映射器)用于確定請求處理器對象,請求處理器可以是任何對象,只要它們使用了@Controller注解或注解@RequestMapping,需要的朋友可以參考下2023-08-08