并发工具---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则是在一个地方等你,你们都到齐了,在执行线程

相关文章
相关标签/搜索