Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解
CountDownLatch
CountDownLatch
是一個(gè)同步輔助類,它允許一個(gè)或多個(gè)線程等待,直到其他線程完成一組操作。CountDownLatch
有一個(gè)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器減為0時(shí),等待的線程將被喚醒。計(jì)數(shù)器只能減少,不能增加。
示例:使用CountDownLatch等待所有線程完成任務(wù)
假設(shè)我們有一個(gè)任務(wù)需要三個(gè)子任務(wù)完成,我們可以使用CountDownLatch
來等待所有子任務(wù)完成。
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"); } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)CountDownLatch
并設(shè)置初始計(jì)數(shù)器為3。每個(gè)子任務(wù)完成后,調(diào)用latch.countDown()
減少計(jì)數(shù)器。主線程調(diào)用latch.await()
等待所有子任務(wù)完成。
CyclicBarrier
CyclicBarrier
是一個(gè)同步輔助類,它允許一組線程相互等待,直到所有線程都準(zhǔn)備好繼續(xù)執(zhí)行。當(dāng)所有線程都到達(dá)屏障點(diǎn)時(shí),屏障將打開。CyclicBarrier
可以重復(fù)使用。
示例:使用CyclicBarrier同步多個(gè)線程
假設(shè)我們有三個(gè)線程需要在某個(gè)點(diǎn)同步,我們可以使用CyclicBarrier
實(shí)現(xiàn)這個(gè)目的。
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(); } } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)CyclicBarrier
并設(shè)置參與者數(shù)量為3。每個(gè)線程在準(zhǔn)備好繼續(xù)執(zhí)行之前調(diào)用barrier.await()
。當(dāng)所有線程都準(zhǔn)備好時(shí),屏障將打開,所有線程將繼續(xù)執(zhí)行。
Semaphore
Semaphore
是一個(gè)計(jì)數(shù)信號(hào)量,它維護(hù)了一個(gè)許可集。線程可以請(qǐng)求許可,如果有可用的許可,線程將獲得許可并繼續(xù)執(zhí)行。否則,線程將阻塞,直到有可用的許可。許可可以由任何線程釋放。Semaphore
可用于實(shí)現(xiàn)資源池、限制并發(fā)訪問等。
示例:使用Semaphore限制并發(fā)訪問
假設(shè)我們有一個(gè)只能同時(shí)處理三個(gè)請(qǐng)求的服務(wù)器,我們可以使用Semaphore
來實(shí)現(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(); } } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)Semaphore
并設(shè)置初始許可數(shù)量為3。每個(gè)客戶端線程在連接服務(wù)器之前調(diào)用semaphore.acquire()
請(qǐng)求許可。當(dāng)許可可用時(shí),線程將獲得許可并繼續(xù)執(zhí)行。線程完成后,調(diào)用semaphore.release()
釋放許可。
Exchanger
Exchanger
是一個(gè)同步輔助類,它允許兩個(gè)線程在一個(gè)臨界點(diǎn)交換數(shù)據(jù)。當(dāng)兩個(gè)線程都到達(dá)交換點(diǎn)時(shí),它們將交換數(shù)據(jù)。Exchanger
可以用于遺傳算法、管道設(shè)計(jì)等。
示例:使用Exchanger交換數(shù)據(jù)
假設(shè)我們有兩個(gè)線程,一個(gè)生成數(shù)據(jù),另一個(gè)處理數(shù)據(jù)。我們可以使用Exchanger
在這兩個(gè)線程之間交換數(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(); } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)Exchanger
。生產(chǎn)者和消費(fèi)者線程在交換數(shù)據(jù)前調(diào)用exchanger.exchange(data)
。當(dāng)兩個(gè)線程都到達(dá)交換點(diǎn)時(shí),它們將交換數(shù)據(jù)。
Phaser
Phaser
是一個(gè)靈活的同步輔助類,它允許一組線程相互等待,直到所有線程都準(zhǔn)備好繼續(xù)執(zhí)行。與CyclicBarrier
類似,但Phaser
更加靈活,可以動(dòng)態(tài)調(diào)整參與者數(shù)量和支持多個(gè)階段。
示例:使用Phaser同步多個(gè)線程
假設(shè)我們有三個(gè)線程需要在某個(gè)點(diǎn)同步,我們可以使用Phaser
實(shí)現(xiàn)這個(gè)目的。
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(); } } }
在這個(gè)示例中,我們創(chuàng)建了一個(gè)Phaser
并設(shè)置參與者數(shù)量為3。每個(gè)線程在準(zhǔn)備好繼續(xù)執(zhí)行之前調(diào)用phaser.arriveAndAwaitAdvance()
。當(dāng)所有線程都準(zhǔn)備好時(shí),屏障將打開,所有線程將繼續(xù)執(zhí)行。
這些并發(fā)工具類為Java多線程編程提供了強(qiáng)大的支持,幫助我們更輕松地實(shí)現(xiàn)各種同步和并發(fā)場景。希望這些示例能幫助你理解并掌握這些工具類的用法。
以上就是Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Java并發(fā)工具類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot可視化接口開發(fā)工具magic-api的簡單使用教程
作為Java后端開發(fā),平時(shí)開發(fā)API接口的時(shí)候經(jīng)常需要定義Controller、Service、Dao、Mapper、XML、VO等Java對(duì)象。有沒有什么辦法可以讓我們不寫這些代碼,直接操作數(shù)據(jù)庫生成API接口呢?今天給大家推薦一款工具magic-api,來幫我們實(shí)現(xiàn)這個(gè)小目標(biāo)!2021-06-06SpringBoot整合rockerMQ消息隊(duì)列詳解
今天和大家一起深入生產(chǎn)級(jí)別消息中間件 - RocketMQ 的內(nèi)核實(shí)現(xiàn),來看看真正落地能支撐萬億級(jí)消息容量、低延遲的消息隊(duì)列到底是如何設(shè)計(jì)的。我會(huì)先介紹整體的架構(gòu)設(shè)計(jì),然后再深入各核心模塊的詳細(xì)設(shè)計(jì)、核心流程的剖析2022-07-07Java實(shí)現(xiàn)的獲取和判斷文件頭信息工具類用法示例
這篇文章主要介紹了Java實(shí)現(xiàn)的獲取和判斷文件頭信息工具類,結(jié)合實(shí)例形式分析了Java針對(duì)文件讀取及頭信息判斷相關(guān)操作技巧,需要的朋友可以參考下2017-11-11Oracle + Mybatis實(shí)現(xiàn)批量插入、更新和刪除示例代碼
利用MyBatis動(dòng)態(tài)SQL的特性,我們可以做一些批量的操作,下面這篇文章主要給大家介紹了關(guān)于Oracle + Mybatis實(shí)現(xiàn)批量插入、更新和刪除的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2018-01-01利用solr實(shí)現(xiàn)商品的搜索功能(實(shí)例講解)
下面小編就為大家分享一篇利用solr實(shí)現(xiàn)商品的搜索功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-11-11Mybatis實(shí)現(xiàn)Mapper動(dòng)態(tài)代理方式詳解
這篇文章主要為大家詳細(xì)介紹了Mybatis實(shí)現(xiàn)Mapper動(dòng)態(tài)代理方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08SpringMVC中的HandlerMapping和HandlerAdapter詳解
這篇文章主要介紹了SpringMVC中的HandlerMapping和HandlerAdapter詳解,在Spring MVC中,HandlerMapping(處理器映射器)用于確定請(qǐng)求處理器對(duì)象,請(qǐng)求處理器可以是任何對(duì)象,只要它們使用了@Controller注解或注解@RequestMapping,需要的朋友可以參考下2023-08-08Java基礎(chǔ)之?dāng)?shù)組的初始化過程
Java數(shù)組分為靜態(tài)和動(dòng)態(tài)初始化,靜態(tài)初始化中,程序員設(shè)定元素初始值,系統(tǒng)決定長度;動(dòng)態(tài)初始化中,程序員設(shè)定長度,系統(tǒng)提供初始值,數(shù)組初始化后長度固定,存儲(chǔ)在堆內(nèi)存中,數(shù)組變量在棧內(nèi)存指向堆內(nèi)存數(shù)組對(duì)象,基本類型數(shù)組存儲(chǔ)數(shù)據(jù)值,引用類型數(shù)組存儲(chǔ)對(duì)象引用2024-10-10