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是加计数方式。