CountDownLatch

Case:假如一个页面要请求的数据很多,需要分开请求各个小模块的数据,只有当所有的请求都完成后,才能执行下一步任务。

先写一个白纸一样的代码

public class CountDownLatchDemo {

    public static void main(String[] args) {

        for (int i = 1; i <= 6; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("线程:\t"+Thread.currentThread().getName()+"\t 执行完毕");
                }
            },String.valueOf(i)).start();
        }

        System.out.println("所有的线程都执行完毕,进入下一个环接!!!");
    }
}

---打印结果-----
线程:	2	 执行完毕
所有的线程都执行完毕,进入下一个环接!!!
线程:	3	 执行完毕
线程:	1	 执行完毕
线程:	5	 执行完毕
线程:	6	 执行完毕
线程:	4	 执行完毕

    才执行完一个请求,就直接说进入下一个环接了... ...失败

    然后启用CountDownLatch...

public class CountDownLatchDemo {

    public static void main(String[] args) {

        int count = 6;
        final CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 1; i <= count; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("线程:\t"+Thread.currentThread().getName()+"\t 执行完毕");
                    countDownLatch.countDown();
                }
            },String.valueOf(i)).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有的线程都执行完毕,进入下一个环接!!!");
    }
}

---打印结果------
线程:	1	 执行完毕
线程:	2	 执行完毕
线程:	3	 执行完毕
线程:	4	 执行完毕
线程:	6	 执行完毕
线程:	5	 执行完毕
所有的线程都执行完毕,进入下一个环接!!!

    完美~

   em......感觉就写这么个“线程 x 执行完毕”没啥意思,再搞点有意思的......

Case...Update:简单模拟一个秦灭六国,一统天下的情景

public class CountDownLatchDemo {

    public static void main(String[] args) {

        int count = 6;
        final CountDownLatch downLatch = new CountDownLatch(6);
        for (int i = 1; i <=count; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("大秦灭掉了\t"+Thread.currentThread().getName()+"\t!");
                    downLatch.countDown();
                }
            },getCountryName(i)).start();
        }
        try {
            downLatch.await();
            System.out.println("大秦已灭六国,一统天下!!!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private static String getCountryName(int i) {
        if (i == 1){
            return "韩国";
        }else if (i == 2){
            return "赵国";
        }else if (i == 3){
            return "魏国";
        }else if (i == 4){
            return "楚国";
        }else if (i == 5){
            return "燕国";
        }else if (i == 6){
            return "齐国";
        }
        return "某国";
    }
}

---打印结果-------
大秦灭掉了	韩国	!
大秦灭掉了	齐国	!
大秦灭掉了	燕国	!
大秦灭掉了	楚国	!
大秦灭掉了	魏国	!
大秦灭掉了	赵国	!
大秦已灭六国,一统天下!!!

   完美.......中有那么一丢丢瑕疵......

      因为其中涉及到的国家的名字是通过if ... else ...的方式一个一个比对出来的,如果是前几个比对成功还好,如果是最后一次才比对成功,那要比6次,这才6个,要是排列水浒108将.......最坏要比107次......如果比对的是全球的国家呢.......阔怕,咋整?

Case—Update—Again:不要用if...else...

public enum  CountryEnum {

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

    int index;
    String name;

    CountryEnum(int index, String name) {
        this.index = index;
        this.name = name;
    }

    public static String getCountryName(int i){
       CountryEnum[] array =  CountryEnum.values();
        for (CountryEnum countryEnum : array) {
            if (i ==countryEnum.index) return countryEnum.name;
        }
        return "某国";
    }
}


public class CountDownLatchDemo {

    public static void main(String[] args) {

        int count = 6;
        final CountDownLatch downLatch = new CountDownLatch(6);
        for (int i = 1; i <=count; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("大秦灭掉了\t"+Thread.currentThread().getName()+"\t!");
                    downLatch.countDown();
                }
            },CountryEnum.getCountryName(i)).start();
        }
        try {
            downLatch.await();
            System.out.println("大秦已灭六国,一统天下!!!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

- -- - - - - - 
大秦灭掉了	韩国	!
大秦灭掉了	赵国	!
大秦灭掉了	魏国	!
大秦灭掉了	燕国	!
大秦灭掉了	齐国	!
大秦灭掉了	楚国	!
大秦已灭六国,一统天下!!!

        这里用了枚举类,主要是枚举的这种使用方式ONE(1,value1,value2,...),就相当于一个数据库表一样。

最后再来介绍这篇的主咖:CountDownLatch

  • 它让一些线程阻塞,直到另一些线程完成一系列操作后才被唤醒
  • 主要有两个方法,当一个或多个线程调用 await 方法时调用线程会被阻塞,其他线程调用 countDown 方法会将计数器减1,当计数器数值变为 0 时,之前调用await方法被阻塞的线程就会被唤醒继续执行

   可以实现这种需求的不止 CountDownLatch 一个,还有他的胞弟:CyclicBarrier

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值