您当前的位置: 首页 > 

星夜孤帆

暂无认证

  • 4浏览

    0关注

    626博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

CountDownLatch解析

星夜孤帆 发布时间:2020-12-01 14:38:41 ,浏览量:4

一、场景

班里有七名同学,放学后,七名同学走完,班长关门走人。

二、普通方法
public class CountDownLatchDemo {
    public static void main(String[] args) {
        for (int i=0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t上完自习,离开教室");
            }, String.valueOf(i)).start();
        }
        System.out.println(Thread.currentThread().getName() + "\t **************班长最后关门走人");
    }
}

班长,先关门走人了??把他们都锁班级里了?

三、CountDownLatch 3.1 概念

让一些线程阻塞,直到另外一些完成后才被唤醒。

CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞,其他线程调用countDown方法,计数器减1(调用countDown方法时线程不会阻塞),当计数器的值变为0,因调用await方法被阻塞的线程会被唤醒,继续执行

countDownLatch这个类,使一个线程等待其他线程各自执行完毕后再执行

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就减1,当计数器的值为0时,表示所有线程都执行完毕,然后,再闭锁上等待的线程就可以恢复工作了

3.2 源码

countDownLatch类中只提供了一个构造器:

//参数count为计数值
public CountDownLatch(int count) {  };  

类中有三个方法是最重要的:

//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };   
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
//将count值减1
public void countDown() { };  
 3.2 关门问题
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6); //设置班级同学总数为6
        for (int i=0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t上完自习,离开教室");
                countDownLatch.countDown(); //班级同学走一个减一个1
            }, String.valueOf(i)).start();
        }
        countDownLatch.await(); //上面的走完,我下面的主线程才能走,控制前面的任务完成以后,才能进行后面的任务
        System.out.println(Thread.currentThread().getName() + "\t **************班长最后关门走人");
    }
}

成功解决上述问题

3.3 秦灭六国问题
public enum CountryEnum {

    ONE(1, "齐"),
    TWO(2, "楚"),
    THREE(3, "燕"),
    FOUR(4, "赵"),
    FIVE(5, "魏"),
    SIX(6, "韩");

    @Getter
    private Integer retCode;

    @Getter
    private String retMessage;

    CountryEnum(Integer retCode, String retMessage) {
        this.retCode = retCode;
        this.retMessage = retMessage;
    }
    public static CountryEnum forEach_CountryEnmu(int index) {
        CountryEnum[] enums = CountryEnum.values();
        for (CountryEnum countryEnum : enums) {
            if (index == countryEnum.getRetCode()) {
                return countryEnum;
            }
        }
        return null;
    }
}
public class CountDownLatchDemo {

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i=1; i  {
                System.out.println(Thread.currentThread().getName() + "\t 国,被灭");
                countDownLatch.countDown();
            }, CountryEnum.forEach_CountryEnmu(i).getRetMessage()).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() + "\t *******************秦帝国,一统华夏");
    }


    public static void closeDoor(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6); //设置班级同学总数为6
        for (int i=0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t上完自习,离开教室");
                countDownLatch.countDown(); //班级同学走一个减一个1
            }, String.valueOf(i)).start();
        }
        countDownLatch.await(); //上面的走完,我下面的主线程才能走,控制前面的任务完成以后,才能进行后面的任务
        System.out.println(Thread.currentThread().getName() + "\t **************班长最后关门走人");
    }
}

参考,视频教程

关注
打赏
1636984416
查看更多评论
立即登录/注册

微信扫码登录

0.1124s