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