併發工具---CountDownLatch和CyclicBarrier

CountDownLatch

理解: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

理解: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();
        }
    }
}

比較 CountDownLatch和CyclicBarrier

1 CountDownLatch是-1,CyclicBarrier是+1dom

2 CountDownLatch須要手動調用countDown() -1 ,而CyclicBarrier不須要手動調用方法則可+1,最終二者都是經過await()方法喚起spa

3 CountDownLatch偏向於多線程合做,東西都準備好了,在執行後續邏輯,CyclicBarrier則是在一個地方等你,你們都到齊了,在執行線程

相關文章
相關標籤/搜索