ava併發程式設計之併發工具類CountDownLatch,CyclicBarrier,Semaphore詳解(轉)
1 前言
在JDK的併發包裡提供了幾個非常有用的併發工具類。CountDownLatch、CyclicBarrier和 Semaphore工具類提供了一種併發流程控制的手段,Exchanger工具類則提供了線上程間交換數 據的一種手段。本文會對這些併發工具類進行介紹。
2 等待多執行緒完成的CountDownLatch
2.1 CountDownLatch案例演示
countdownlatch 是一個同步工具類,它允許一個或多個執行緒一直等待,直到其他執行緒的操作執行完畢再執行。從命名可以解讀到 countdown 是倒數的意思,類似於我們倒計時的概念。
countdownlatch 提供了兩個方法,一個是 countDown,一個是 await,countdownlatch 初始化的時候需要傳入一個整數,在這個整數倒數到 0 之前,呼叫了 await 方法的程式都必須要等待,然後通過 countDown 來倒數。
public class CountDownLatchDemo { public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(6); for (int i = 0; i < 6; i++) { new Thread(() -> { System.out.println(Thread.currentThread().getName()+"同學離開了"); countDownLatch.countDown(); }).start(); }try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"要關門了,此時教室已經沒人了~"); } }
3 同步屏障CyclicBarrier
CyclicBarrier的字面意思是可迴圈使用(Cyclic)的屏障(Barrier)。它要做的事情是,讓一 組執行緒到達一個屏障(也可以叫同步點)時被阻塞,直到最後一個執行緒到達屏障時,屏障才會 開門,所有被屏障攔截的執行緒才會繼續執行。
3.1 CyclicBarrier使用場景
使用場景:5個工程師一起來公司應聘,招聘方式分為筆試和麵試。首先,要等人到齊後,開始筆試;筆試結束之後,再一起參加面試。把5個人看作5個執行緒,程式碼如下:
Main類
public class Main { public static void main(String[] args) throws BrokenBarrierException, InterruptedException { CyclicBarrier barrier = new CyclicBarrier(5); for (int i = 0; i < 5; i++) { new MyThread("執行緒-" + (i + 1), barrier).start(); } } }
MyThread類:
public class MyThread extends Thread{ private final CyclicBarrier barrier; private final Random random = new Random(); public MyThread(String name, CyclicBarrier barrier) { super(name); this.barrier = barrier; } @Override public void run() { try { Thread.sleep(random.nextInt(2000)); System.out.println(Thread.currentThread().getName() + " - 已經到達公司"); barrier.await(); Thread.sleep(random.nextInt(2000)); System.out.println(Thread.currentThread().getName() + " - 已經筆試結束"); barrier.await(); Thread.sleep(random.nextInt(2000)); System.out.println(Thread.currentThread().getName() + " - 已經面試結束"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } super.run(); } }
在整個過程中,有2個同步點:第1個同步點,要等所有應聘者都到達公司,再一起開始筆試;第2個同步點,要等所有應聘者都結束筆試,之後一起進入面試環節。
3.3 CyclicBarrier與CountDownLatch 區別
CountDownLatch 是一次性的,CyclicBarrier 是可迴圈利用的
CountDownLatch的計數器只能使用一次,而CyclicBarrier的計數器可以使用reset()方法重置,可以使用多次,所以CyclicBarrier能夠處理更為複雜的場景;
4 控制併發執行緒數的Semaphore
Semaphore(訊號量)是用來控制同時訪問特定資源的執行緒數量,它通過協調各個執行緒,以 保證合理的使用公共資源
4.1 Semaphore的使用場景
public class SemaphoreDemo { public static void main(String[] args) { Semaphore semaphore=new Semaphore(3);//此時海底撈有3個空桌 for (int i = 0; i < 6; i++) { new Thread(() -> { try { semaphore.acquire(); System.out.println("第"+Thread.currentThread().getName()+"等待者搶到座位。"); //假設每桌客人吃飯時間為3S TimeUnit.SECONDS.sleep(3); System.out.println("第"+Thread.currentThread().getName()+"客人吃完飯離開。"); } catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); } },String.valueOf(i)).start(); } } }
作者:幹天慈雨
連結:https://www.jianshu.com/p/6251c13bbb2e
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。