理解:countDownLatch是一個程序計數器,線程的執行有快有慢,當一個線程執行完成以後,不當即返回,調用countdown(),對初始化數量-1,等待其餘線程執行完成,只有當所有的線程執行完成以後才返回,即countDownLatch=0,調用await()釋放鎖,執行後續操做 java
package src.main.concurrent.currenttools; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * 程序計數器 * 模擬場景:用戶查詢機票,三個線程,分別去不一樣的航空公司查詢,而後統一返回結果 * <p> * 其餘 * Arrays.asList(); 直接爲list賦值 * System.out.printf("%s 當前航空公司",Thread.currentThread().getName()); * airInfos.forEach(System.out::println); lambda表達式 * * @author admin * @version $Id: CountDownLatchQuery.java, v 0.1 2018年10月20日 17:30 admin Exp $ */ public class CountDownLatchQuery { //航空公司列表 private static List<String> airComponyList = Arrays.asList("南方航空公司", "中國航空公司", "北方航空公司"); // 航空信息列表 private static List<String> airInfos = new ArrayList<>(); //起點 private static final String start = "南京"; //終點 private static final String end = "深圳"; public CountDownLatchQuery(int length) {} public static void main(String[] args) throws InterruptedException { Thread[] searchThreads = new Thread[airComponyList.size()]; CountDownLatch countDownLatchQuery = new CountDownLatch(searchThreads.length); for (int i = 0; i < searchThreads.length; i++) { String threadName = airComponyList.get(i); searchThreads[i] = new Thread(() -> { //隨機數產生剩餘的票數 int oddTickects = new Random().nextInt(10); //休眠時間取餘票的隨機數 int sleepTime = oddTickects; try { TimeUnit.SECONDS.sleep(sleepTime); String airInfo = threadName + ":剩餘票數:" + oddTickects; airInfos.add(airInfo); } catch (InterruptedException e) { e.printStackTrace(); } finally { countDownLatchQuery.countDown(); } }); searchThreads[i].start(); } countDownLatchQuery.await(); airInfos.forEach(System.out::println); airInfos.forEach((String s) -> { System.out.println(s); }); } }
理解:CyClicBarrier能夠理解爲跑道,每一個線程至關於一個運動員,全部線程都到達了起跑線以後,才能開始,最早到達的運動員要等待其餘都到達以後,才能開始,同理,每一個線程只有在都到達柵欄的時候才能開始工做,每就緒一個就+1,直到與給定的數量相同時,釋放,同時執行後續操做 多線程
package src.main.concurrent.currenttools; import java.util.Random; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.TimeUnit; /** * CyclicBarrierTest 循環柵欄 * * 模擬8個運動員,使他們到達柵欄的時間不一樣,最後統一釋放 * * @author admin * @version $Id: CyclicBarrierTest.java, v 0.1 2018年10月21日 17:27 admin Exp $ */ public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier=new CyclicBarrier(8); //模擬8個運動員 Thread [] sportThreads=new Thread[8]; for(int i=0;i<8;i++){ sportThreads[i]=new Thread(()->{ try { TimeUnit.SECONDS.sleep(new Random().nextInt(10)); System.out.println(Thread.currentThread().getName()+"已就緒"); cyclicBarrier.await(); } catch (Exception e) { e.printStackTrace(); } },"sprotThread["+i+"]"); sportThreads[i].start(); } try { TimeUnit.SECONDS.sleep(10); System.out.println("比賽開始 start........"); } catch (InterruptedException e) { e.printStackTrace(); } } }
1 CountDownLatch是-1,CyclicBarrier是+1dom
2 CountDownLatch須要手動調用countDown() -1 ,而CyclicBarrier不須要手動調用方法則可+1,最終二者都是經過await()方法喚起spa
3 CountDownLatch偏向於多線程合做,東西都準備好了,在執行後續邏輯,CyclicBarrier則是在一個地方等你,你們都到齊了,在執行線程