Java多執行緒之JUC輔助類
阿新 • • 發佈:2020-12-15
1. JUC輔助類
1.1 CountDownLatch
- 減少計數
- 方法
- await() / await(long timeout, TimeUnit unit) (unit 時間單位)
- 阻塞,直到count為0,或執行緒被中斷,或達到給定的時間
- countDown()
- 計數減一,直到為0,釋放等待執行緒
- await() / await(long timeout, TimeUnit unit) (unit 時間單位)
- 當一個或多個執行緒呼叫await方法時,這些執行緒會阻塞,其它執行緒呼叫countDown方法會將計數器減1(呼叫countDown方法的執行緒不會阻塞),當計數器的值變為0時,因await方法阻塞的執行緒會被喚醒,繼續執行。
public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { CountDownLatch count = new CountDownLatch(6); for (int i = 0; i < 6; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName()+"\t 離開"); count.countDown(); }, String.valueOf(i)).start(); } count.await();//阻塞,直到count=0,main執行緒才繼續向下執行 System.out.println("全部離開"); } }
1.2 CyclicBarrier
- 可迴圈(Cyclic)使用的屏障(Barrier)。它要做的事情是,讓一組執行緒到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續幹活。執行緒進入屏障通過CyclicBarrier的await()方法
public class CyclicBarrierDemo { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() -> { System.out.println("召喚神龍"); }); for (int i = 1; i <= 7; i++) { new Thread(() -> { System.out.println("獲得第"+Thread.currentThread().getName()+"顆龍珠!"); try { cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println("執行緒"+Thread.currentThread().getName()+"====>"+ Thread.currentThread().getState()); }, String.valueOf(i)).start(); } } } /* 獲得第1顆龍珠! 獲得第4顆龍珠! 獲得第5顆龍珠! 獲得第3顆龍珠! 獲得第2顆龍珠! 獲得第6顆龍珠! 獲得第7顆龍珠! 召喚神龍 執行緒5====>RUNNABLE 執行緒3====>RUNNABLE 執行緒2====>RUNNABLE 執行緒1====>RUNNABLE 執行緒6====>RUNNABLE 執行緒4====>RUNNABLE 執行緒7====>RUNNABLE */
1.3 Semaphore
- 在訊號量上我們定義兩種操作:
- acquire(獲取) 當一個執行緒呼叫acquire操作時,它要麼通過成功獲取訊號量(訊號量減1),要麼一直等下去,直到有執行緒釋放訊號量,或超時。
- release(釋放)實際上會將訊號量的值加1,然後喚醒等待的執行緒。
- 訊號量主要用於兩個目的,一個是用於多個共享資源的互斥使用,另一個用於併發執行緒數的控制。
public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 6; i++) { new Thread(() -> { try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "\t搶到車位!"); TimeUnit.SECONDS.sleep(new Random().nextInt(5)); System.out.println(Thread.currentThread().getName() + "\t離開"); } catch (Exception e) { e.printStackTrace(); } finally { semaphore.release(); } }, String.valueOf(i)).start(); } } } /* 2 搶到車位! 1 搶到車位! 6 搶到車位! 1 離開 6 離開 4 搶到車位! 3 搶到車位! 3 離開 5 搶到車位! 2 離開 4 離開 5 離開 */