JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解
JUC 中提供了三種常用的輔助類,通過這些輔助類可以很好的解決線程數(shù)量過多時 Lock 鎖的頻繁操作。
這三種輔助類為:
CountDownLatch: 減少計數(shù)
CyclicBarrier: 循環(huán)柵欄
Semaphore: 信號燈
減少計數(shù) CountDownLatch
CountDownLatch 類可以設(shè)置一個計數(shù)器,然后通過 countDown 方法來進行 減 1 的操作,使用 await 方法等待計數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法 之后的語句。
- CountDownLatch 主要有兩個方法,當一個或多個線程調(diào)用 await 方法時,這 些線程會阻塞
- 其它線程調(diào)用 countDown 方法會將計數(shù)器減 1(調(diào)用 countDown 方法的線程 不會阻塞)
- 當計數(shù)器的值變?yōu)?0 時,因 await 方法阻塞的線程會被喚醒,繼續(xù)執(zhí)行
場景: 6 個同學陸續(xù)離開教室后值班同學才可以關(guān)門。
//演示 CountDownLatch public class CountDownLatchDemo { //6個同學陸續(xù)離開教室之后,班長鎖門 public static void main(String[] args) throws InterruptedException { //創(chuàng)建CountDownLatch對象,設(shè)置初始值 CountDownLatch countDownLatch = new CountDownLatch(6); //6個同學陸續(xù)離開教室之后 for (int i = 1; i <=6; i++) { new Thread(()->{ System.out.println(Thread.currentThread().getName()+" 號同學離開了教室"); //計數(shù)器減一,不會阻塞 countDownLatch.countDown(); },String.valueOf(i)).start(); } //主線程 await 休息 countDownLatch.await(); //全部離開后自動喚醒主線程 是指計數(shù)器不大于 0,然后繼續(xù)執(zhí)行 await 方法之后的語句。 System.out.println("全部離開了,現(xiàn)在的計數(shù)器為" + countDownLatch.getCount()); System.out.println(Thread.currentThread().getName()+" 班長鎖門走人了"); } }
循環(huán)柵欄 CyclicBarrier.
CyclicBarrier 看英文單詞可以看出大概就是循環(huán)阻塞的意思,在使用中CyclicBarrier 的構(gòu)造方法第一個參數(shù)是目標障礙數(shù),每次執(zhí)行 CyclicBarrier 一 次障礙數(shù)會加一,如果達到了目標障礙數(shù),才會執(zhí)行 cyclicBarrier.await()之后 的語句 。可以將 CyclicBarrier 理解為加 1 操作
常用的構(gòu)造方法有:
CyclicBarrier(int parties,Runnable barrierAction)創(chuàng)建一個新的CyclicBarrier,它將在給定數(shù)量的參與者(線程)處于等待狀態(tài)時啟動,并在啟動barrier時執(zhí)行給定的屏障操作,該操作由最后一個進入barrier的線程操作
常用的方法有:
await() 在所有的參與者都已經(jīng)在此barrier上調(diào)用await方法之前一直等待
場景: 集齊 7 顆龍珠就可以召喚神龍
//集齊7顆龍珠就可以召喚神龍 public class CyclicBarrierDemo { //創(chuàng)建固定值 private static final int NUMBER = 7; public static void main(String[] args) { //創(chuàng)建CyclicBarrier CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER,()->{ System.out.println("*****集齊7顆龍珠就可以召喚神龍"); }); //集齊七顆龍珠過程 for (int i = 1; i <=7; i++) { new Thread(()->{ try { System.out.println(Thread.currentThread().getName()+" 星龍被收集到了"); //等待 cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } }
信號燈 Semaphore
Semaphore 的構(gòu)造方法中傳入的第一個參數(shù)是最大信號量(可以看成最大線程池),每個信號量初始化為一個最多只能分發(fā)一個許可證。
使用 acquire 方法獲得許可證 , release 方法釋放許可
場景: 搶車位, 6 部汽車 3 個停車位
具體常用的構(gòu)造方法有:Semaphore(int permits)創(chuàng)建具有給定的許可數(shù)和非公平的公平設(shè)置的Semapore
具體常用的方法有:acquire()從此信號量獲取一個許可,在提供一個許可前一直將線程阻塞,否則線程被中斷release() 釋放一個許可,將其返回給信號量
設(shè)置許可數(shù)量Semaphore semaphore = new Semaphore(3); 一般acquire()都會拋出異常,release在finally中執(zhí)行
//6輛汽車,停3個車位 public class SemaphoreDemo { public static void main(String[] args) { //創(chuàng)建Semaphore,設(shè)置許可數(shù)量 Semaphore semaphore = new Semaphore(3); //模擬6輛汽車 for (int i = 1; i <=6; i++) { new Thread(()->{ try { //搶占 semaphore.acquire(); System.out.println(Thread.currentThread().getName()+" 搶到了車位"); //設(shè)置隨機停車時間 TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println(Thread.currentThread().getName()+" ------離開了車位"); } catch (InterruptedException e) { e.printStackTrace(); } finally { //釋放 semaphore.release(); } },String.valueOf(i)).start(); } } }
到此這篇關(guān)于JUC三大輔助類CountDownLatch、CyclicBarrier和Semaphore詳解的文章就介紹到這了,更多相關(guān)CountDownLatch、CyclicBarrier和Semaphore內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于mybatis調(diào)用存儲過程獲取返回值問題
這篇文章主要介紹了mybatis調(diào)用存儲過程獲取返回值問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01一小時迅速入門Mybatis之實體類別名與多參數(shù) 動態(tài)SQL
這篇文章主要介紹了一小時迅速入門Mybatis之實體類別名與多參數(shù) 動態(tài)SQL,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09基于SpringBoot和Vue3的博客平臺文章詳情與評論功能實現(xiàn)
在前面的教程中,我們已經(jīng)實現(xiàn)了基于Spring Boot和Vue3的發(fā)布、編輯、刪除文章功能以及文章列表與分頁功能。本教程將引導您實現(xiàn)博客平臺的文章詳情與評論功能,需要的朋友可以參考一下2023-04-04maven項目后出現(xiàn)‘parent.relativePath’ of POM錯誤時的解決方法
在Springboot項目啟動時,項目報錯‘parent.relativePath’ of POM問題,項目無法正常啟動,本文就來介紹一下解決方法,感興趣的可以了解一下2023-10-10RabbitMQ 在 Spring Boot 項目中的深度應(yīng)用與實戰(zhàn)解析
RabbitMQ 作為一款廣受歡迎的開源消息隊列系統(tǒng),遵循 AMQP 協(xié)議,能夠在分布式系統(tǒng)里實現(xiàn)應(yīng)用程序之間的異步通信、解耦以及流量削峰等關(guān)鍵功能,這篇文章主要介紹了RabbitMQ 在 Spring Boot 項目中的深度應(yīng)用與實戰(zhàn)解析,需要的朋友可以參考下2025-01-01