Java併發基礎:CountDownLatch和CyclicBarrier
阿新 • • 發佈:2018-12-09
CountDownLatch概括
CountDownLatch能夠使一個執行緒在等待其他一個或多個執行緒執行結束之後,再繼續執行。
使用一個計數器進行實現。計數器初始值為執行緒的數量。當每一個執行緒完成自己任務後,計數器的值就會減一。當計數器的值為0時,表示所有的執行緒都已經完成了任務,然後在CountDownLatch上等待的執行緒就可以恢復執行任務。
CountDownLatch用法
例子:假設現在有t1,t2,t3三個執行緒,保證t3執行緒在t1和t2都執行完成後再執行
package org.cc; import java.util.Random; import java.util.concurrent.CountDownLatch; public class UseCountDownLatch { public static void main(String[] args) { //CountDownLatch(int count) //count如果是2就代表cdl.countDown()兩次 cdl.await()所在的執行緒才能被喚醒 CountDownLatch cdl=new CountDownLatch(2); new Thread(()->{ System.out.println("進入t1執行緒......"); try { //隨機休息1到10秒用來摸你程式執行 Thread.sleep(1000*(new Random().nextInt(10))); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t1執行緒執行結束......"); //cdl.countDown()一次 cdl.countDown(); }).start(); new Thread(()->{ System.out.println("進入t2執行緒......"); try { //隨機休息1到10秒用來摸你程式執行 Thread.sleep(1000*(new Random().nextInt(10))); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2執行緒執行結束......"); //cdl.countDown()兩次 cdl.countDown(); }).start(); new Thread(()->{ System.out.println("進入t3執行緒......"); try { cdl.await(); } catch (InterruptedException e) { e.printStackTrace(); } try { //隨機休息1到10秒用來摸你程式執行 Thread.sleep(1000*(new Random().nextInt(10))); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t3執行緒執行結束......"); cdl.countDown(); }).start(); } }
進入t1執行緒......
進入t3執行緒......
進入t2執行緒......
t1執行緒執行結束......
t2執行緒執行結束......
t3執行緒執行結束......
CyclicBarrier概括
多執行緒的進行阻塞,等待某一個臨界值條件滿足後,同時執行!
CyclicBarrier用法
例子:假設用三個運動員。等3個運動員都準備好之後同時開始起跑;
package org.cc; import java.util.Random; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class UseCyclicBarrier { static class Runner implements Runnable { private String name; private CyclicBarrier cyclic; public Runner(String name, CyclicBarrier cyclic) { this.name = name; this.cyclic = cyclic; } @Override public void run() { System.out.println("運動員" + name + "進入賽道,準備中....."); try { //隨機休息1到10秒用來摸你程式執行 Thread.sleep(1000 * (new Random().nextInt(10))); System.out.println("運動員" + name + "準備結束,等待起跑訊號!!!!"); cyclic.await(); } catch (Exception e) { e.printStackTrace(); } System.out.println("運動員" + name + "起跑!!!!"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public CyclicBarrier getCyclic() { return cyclic; } public void setCyclic(CyclicBarrier cyclic) { this.cyclic = cyclic; } } public static void main(String[] args) { //3代表執行了3次cyclic.await()後結束等待 //此處是代表3個運動員準備好了之後開始起跑 CyclicBarrier c = new CyclicBarrier(3); ExecutorService s = Executors.newFixedThreadPool(3); s.submit(new Runner("張三", c)); s.submit(new Runner("李四", c)); s.submit(new Runner("王五", c)); s.shutdown(); } }
運動員李四進入賽道,準備中.....
運動員王五進入賽道,準備中.....
運動員張三進入賽道,準備中.....
運動員李四準備結束,等待起跑訊號!!!!
運動員王五準備結束,等待起跑訊號!!!!
運動員張三準備結束,等待起跑訊號!!!!
運動員王五起跑!!!!
運動員李四起跑!!!!
運動員張三起跑!!!!
CyclicBarrier和CountDownLatch的區別
假設一共有N個執行緒,CountDownLatch是一個執行緒等待其他N-1個執行緒執行結束後再執行,CyclicBarrier是N個執行緒都準備就緒後同時執行。
CountDownLatch是減計數方式,而CyclicBarrier是加計數方式。