java多線程JUC常用輔助類詳解
1.countDownLatch
減法計(jì)數(shù)器:實(shí)現(xiàn)調(diào)用幾次線程后,在觸發(fā)另一個(gè)任務(wù)
簡(jiǎn)單代碼實(shí)現(xiàn):
舉例說(shuō)明:就像五個(gè)人在同一房間里,有一個(gè)看門的大爺,當(dāng)五個(gè)人都出去后,他才能鎖門,也就是說(shuō) 執(zhí)行5次出門這個(gè)動(dòng)作的線程后,才出發(fā)了鎖門的這個(gè)動(dòng)作
import java.util.concurrent.CountDownLatch; /** * @program: juc * @description * @author: 不會(huì)編程的派大星 * @create: 2021-04-24 16:55 **/ public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(5); System.out.println("door is open"); for (int i = 1; i <= 5 ; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName()+" is going out"); countDownLatch.countDown(); },String.valueOf(i)).start(); } countDownLatch.await(); System.out.println("door is closed"); } }
代碼運(yùn)行結(jié)果:
基本原理:
countDownLatch.countDown(); // 數(shù)量-1
countDownLatch.await(); // 等待計(jì)數(shù)器歸零,然后再向下執(zhí)行
每次有線程調(diào)用 countDown() 數(shù)量-1,假設(shè)計(jì)數(shù)器變?yōu)?,countDownLatch.await() 就會(huì)被喚醒,繼續(xù)執(zhí)行!
2.CyclicBarrier
這里我們簡(jiǎn)單理解為 加法計(jì)數(shù)器
簡(jiǎn)單代碼實(shí)現(xiàn):
舉例說(shuō)明:這里只要集齊7顆龍珠,就執(zhí)行 打印 “7顆龍珠集齊了”的線程,這里我們先設(shè)置線程計(jì)數(shù)為8,看看會(huì)不會(huì)執(zhí)行打印的線程,然后在執(zhí)行計(jì)數(shù)為7的情況
1.cyclicBarrier計(jì)數(shù)為8的時(shí)候,執(zhí)行線程數(shù)量為7的時(shí)候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不會(huì)編程的派大星 * @create: 2021-04-24 17:31 **/ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(8,new myThread()); for (int i = 1; i <= 7 ; i++) { int finalI = i; new Thread(() -> { System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"顆龍珠"); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } class myThread implements Runnable{ @Override public void run() { System.out.println("7顆龍珠集齊啦"); } }
執(zhí)行結(jié)果:
2.cyclicBarrier計(jì)數(shù)為1的時(shí)候,執(zhí)行線程數(shù)量為7的時(shí)候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不會(huì)編程的派大星 * @create: 2021-04-24 17:31 **/ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread()); for (int i = 1; i <= 7 ; i++) { int finalI = i; new Thread(() -> { System.out.println(Thread.currentThread().getName()+"收集了"+ finalI+"顆龍珠"); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } },String.valueOf(i)).start(); } } } class myThread implements Runnable{ @Override public void run() { System.out.println("7顆龍珠集齊啦"); } }
執(zhí)行結(jié)果:
可以看到
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread());
當(dāng)執(zhí)行完7個(gè)線程后,才會(huì)執(zhí)行一個(gè)實(shí)現(xiàn)了Runnable接口的線程
3.Semaphore
簡(jiǎn)單代碼實(shí)現(xiàn):
舉例說(shuō)明:搶車位 ,6個(gè)車,最多同時(shí)只能有三個(gè)車進(jìn)
import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * @program: juc * @description * @author: 不會(huì)編程的派大星 * @create: 2021-04-24 18:26 **/ public class SemaphoreTest { public static void main(String[] args) { //線程數(shù)量 ,停車位,,6輛車在等,最多只能同時(shí)進(jìn)來(lái)三個(gè) 限流 Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 6 ; i++) { new Thread(() -> { try { semaphore.acquire();//獲得 System.out.println(Thread.currentThread().getName()+"搶到車位了"); TimeUnit.SECONDS.sleep(3); System.out.println(Thread.currentThread().getName()+"離開(kāi)車位了"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); //釋放 } },String.valueOf(i)).start(); } } }
運(yùn)行結(jié)果:
原理說(shuō)明:
semaphore.acquire()
; 獲得,假設(shè)如果已經(jīng)滿了,等待,等待被釋放為止!
semaphore.release()
; 釋放,會(huì)將當(dāng)前的信號(hào)量釋放 + 1,然后喚醒等待的線程!
作用: 多個(gè)共享資源互斥的使用!并發(fā)限流,控制最大的線程數(shù)!
以上就是java多線程JUC常用輔助類詳解的詳細(xì)內(nèi)容,更多關(guān)于java多線程JUC輔助類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java后端向前端返回文件流實(shí)現(xiàn)下載功能
后端可以使用Java中servlet提供的HttpServletResponse,核心步驟是要設(shè)置響應(yīng)的數(shù)據(jù)類型,設(shè)置為某一類文件類型或二進(jìn)制格式,以及響應(yīng)頭,然后用ServletOutputStream將文件以流的形式發(fā)送到前端,本文介紹Java后端向前端返回文件流實(shí)現(xiàn)下載功能,感興趣的朋友一起看看吧2023-12-12form表單回寫(xiě)技術(shù)java實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)form表單回寫(xiě)技術(shù)的相關(guān)資料,需要的朋友可以參考下2016-04-04Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置三種方法
時(shí)間和日期的統(tǒng)一設(shè)置在項(xiàng)目中經(jīng)常是會(huì)遇到的,下面這篇文章主要給大家介紹了關(guān)于Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置的三種方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-08-08springboot內(nèi)置tomcat調(diào)優(yōu)并發(fā)線程數(shù)解析
這篇文章主要介紹了springboot內(nèi)置tomcat調(diào)優(yōu)并發(fā)線程數(shù)解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java中你的項(xiàng)目應(yīng)該如何正確分層
這篇文章主要介紹了java中你的項(xiàng)目應(yīng)該如何正確分層,業(yè)務(wù)分層對(duì)于代碼規(guī)范是比較重要,決定著以后的代碼是否可復(fù)用,感興趣的可以了解一下2021-04-04Idea 配置國(guó)內(nèi) Maven 源的圖文教程
這篇文章主要介紹了Idea 配置國(guó)內(nèi) Maven 源的教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11Spring Boot中使用Activiti的方法教程(二)
工作流(Workflow),就是“業(yè)務(wù)過(guò)程的部分或整體在計(jì)算機(jī)應(yīng)用環(huán)境下的自動(dòng)化”,下面這篇文章主要給大家介紹了關(guān)于Spring Boot中使用Activiti的相關(guān)資料,需要的朋友可以參考下2018-08-08