java 併發包同步 CountDownLatch, CyclicBarrier, Semaphore
阿新 • • 發佈:2018-12-18
java 執行緒併發包
- 通常為java.util.concurrent 下的包
執行緒包提供的同步結構主要有三個
- CountDownLatch
- CyclicBarrier
- Semaphore
CountDownLatch
- CountDownLatch 允許一個執行緒或多個執行緒等待某些操作完成,一般用於等待事件的促發
- 例項:
/** * @Author: gsonp * @Date: 2018/10/10 20:42 */ public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch=new CountDownLatch(1); Thread a=new Thread(new RunnerA(countDownLatch)); a.start(); Thread b=new Thread(new RunnerB(countDownLatch)); b.start(); } public static class RunnerA implements Runnable{ CountDownLatch countDownLatch; public RunnerA(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { System.out.println("阻塞 等待B執行完成"); try { countDownLatch.await(); } catch (InterruptedException e) { } System.out.println("B執行緒執行完成"); } } public static class RunnerB implements Runnable{ CountDownLatch countDownLatch; public RunnerB(CountDownLatch countDownLatch) { this.countDownLatch = countDownLatch; } @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { } System.out.println("喚醒A 執行緒"); countDownLatch.countDown(); } } }
執行結果:
阻塞B等待執行完成
喚醒A 執行緒
B執行緒執行完成
- CountDownLatch 缺點: CountDownLatch 計數器只有在物件建立的時候被初始化,變為0的時候,就無法再次使用
CyclicBarrier
- CyclicBarier 允許多個執行緒到達一個屏障,執行緒阻塞 當最後一個執行緒到達屏障時,屏障開啟,所有執行緒繼續執行。一般用於在多執行緒計算中,多個執行緒計算完成,主執行緒統計結果
- 例項:
public class CyclicBarrierTest { public static void main(String[] args){ CyclicBarrier cb=new CyclicBarrier(2); Thread a=new Thread(new RunnerA(cb)); a.start(); Thread b=new Thread(new RunnerB(cb)); b.start(); } public static class RunnerA implements Runnable{ CyclicBarrier cb; public RunnerA(CyclicBarrier cb) { this.cb = cb; } @Override public void run() { try { Thread.sleep(2000); System.out.println("A執行到達屏障,等待B執行完成"); cb.await(); System.out.println("B執行完成,A繼續執行"); } catch (Exception e) { e.printStackTrace(); } } } public static class RunnerB implements Runnable{ CyclicBarrier cb; public RunnerB(CyclicBarrier cb) { this.cb = cb; } @Override public void run() { try { Thread.sleep(3000); System.out.println("B執行到達屏障"); cb.await(); System.out.println("B繼續執行"); } catch (Exception e) { e.printStackTrace(); } } } }
當CyclicBarrier 屏障開啟後,會自動重置,不需要收到呼叫reset方法
Semaphore
- Semaphore java 版本的訊號量,設定permit ,限制對通用資源訪問的目的,一般用於對資源訪問的控制
- 例項:
/** * @Author: gsonp * @Date: 2018/10/11 20:19 */ public class SemaphoreTest { public static void main(String[] args){ Semaphore sp=new Semaphore(1); Thread a=new Thread(new RunnerA(sp)); a.start(); Thread b=new Thread(new RunnerB(sp)); b.start(); } public static class RunnerA implements Runnable{ Semaphore sp; public RunnerA(Semaphore sp) { this.sp = sp; } @Override public void run() { try { System.out.println("A執行獲取permit"); sp.acquire(); Thread.sleep(4000); sp.release(); System.out.println("A執行完成,釋放permit"); } catch (Exception e) { e.printStackTrace(); } } } public static class RunnerB implements Runnable{ Semaphore sp; public RunnerB(Semaphore sp) { this.sp = sp; } @Override public void run() { try { System.out.println("B執行等待獲取permit"); sp.acquire(); System.out.println("B執行完畢是否permit"); sp.release(); } catch (Exception e) { e.printStackTrace(); } } } }
Semaphore 一般用於對資源的訪問做限制