1.countDownLatch
減法計數器:實現調用幾次線程后,在觸發另一個任務
簡單代碼實現:
舉例說明:就像五個人在同一房間里,有一個看門的大爺,當五個人都出去后,他才能鎖門,也就是說 執行5次出門這個動作的線程后,才出發了鎖門的這個動作
import java.util.concurrent.CountDownLatch; /** * @program: juc * @description * @author: 不會編程的派大星 * @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"); } }
代碼運行結果:
基本原理:
countDownLatch.countDown(); // 數量-1
countDownLatch.await(); // 等待計數器歸零,然后再向下執行
每次有線程調用 countDown() 數量-1,假設計數器變為0,countDownLatch.await() 就會被喚醒,繼續執行!
2.CyclicBarrier
這里我們簡單理解為 加法計數器
簡單代碼實現:
舉例說明:這里只要集齊7顆龍珠,就執行 打印 “7顆龍珠集齊了”的線程,這里我們先設置線程計數為8,看看會不會執行打印的線程,然后在執行計數為7的情況
1.cyclicBarrier計數為8的時候,執行線程數量為7的時候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不會編程的派大星 * @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顆龍珠集齊啦"); } }
執行結果:
2.cyclicBarrier計數為1的時候,執行線程數量為7的時候:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * @program: juc * @description * @author: 不會編程的派大星 * @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顆龍珠集齊啦"); } }
執行結果:
可以看到
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,new myThread());
當執行完7個線程后,才會執行一個實現了Runnable接口的線程
3.Semaphore
簡單代碼實現:
舉例說明:搶車位 ,6個車,最多同時只能有三個車進
import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * @program: juc * @description * @author: 不會編程的派大星 * @create: 2021-04-24 18:26 **/ public class SemaphoreTest { public static void main(String[] args) { //線程數量 ,停車位,,6輛車在等,最多只能同時進來三個 限流 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()+"離開車位了"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); //釋放 } },String.valueOf(i)).start(); } } }
運行結果:
原理說明:
semaphore.acquire()
; 獲得,假設如果已經滿了,等待,等待被釋放為止!
semaphore.release()
; 釋放,會將當前的信號量釋放 + 1,然后喚醒等待的線程!
作用: 多個共享資源互斥的使用!并發限流,控制最大的線程數!
以上就是java多線程JUC常用輔助類詳解的詳細內容,更多關于java多線程JUC輔助類的資料請關注服務器之家其它相關文章!
原文鏈接:https://blog.csdn.net/weixin_45827693/article/details/116096664