并发专题之--- JUC常用工具类

CountDownLatch

理解: 可以把CountDownLatch看成火箭发射倒计时,也就是当其他条件满足的时候,才开始某个线程的运行.

例子:比如放学了,班长必须等全部同学走完啦,才可以关门,也就是说关门的这个操作,必须放在最后一步.
先看下不用CountDownLatch的的结果

public class SpinDemo {
    public static void main(String[] args) {
        for (int i = 0; i <6 ; i++) {
             new Thread(()->{
                 System.out.println(Thread.currentThread().getName()+"上完自习,离开教室 ");
             },String.valueOf(i)).start();
        }

        System.out.println(Thread.currentThread().getName()+"班长关门走人");
    }
}

2上完自习,离开教室 
main班长关门走人
0上完自习,离开教室 
1上完自习,离开教室 
4上完自习,离开教室 
3上完自习,离开教室 
5上完自习,离开教室 

可以看到,还没有等其他同学走的时候就已经关门…那么如何避免呢

public class SpinDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i <6 ; i++) {
             new Thread(()->{
                 System.out.println(Thread.currentThread().getName()+"上完自习,离开教室 ");
                 countDownLatch.countDown();//走一个减一
             },String.valueOf(i)).start();
        }
       countDownLatch.await(); //班长等着,啥时候6清0啦 才能走
        System.out.println(Thread.currentThread().getName()+"班长关门走人");
    }
}
0上完自习,离开教室 
5上完自习,离开教室 
1上完自习,离开教室 
2上完自习,离开教室 
3上完自习,离开教室 
4上完自习,离开教室 
main班长关门走人

这里添加个枚举

package com.disney.demo;

import javax.xml.bind.Element;

public enum ConntryEnum {
    ONE(0,"齐"),
    TOW(1,"楚"),
    THREE(2,"燕"),
    FOUR(3,"赵"),
    FIVE(4,"魏国"),
    SIX(5,"秦国");

    private  Integer CountryId;
    private  String CountryName;


    ConntryEnum(Integer countryId, String countryName) {
        CountryId = countryId;
        CountryName = countryName;
    }

    public Integer getCountryId() {
        return CountryId;
    }

    public void setCountryId(Integer countryId) {
        CountryId = countryId;
    }

    public String getCountryName() {
        return CountryName;
    }

    public void setCountryName(String countryName) {
        CountryName = countryName;
    }

    public static ConntryEnum forConntryEnum(int index){
        ConntryEnum[] values = ConntryEnum.values();
        for (ConntryEnum conntryEnum : values){
           if (index== conntryEnum.getCountryId()){
               return conntryEnum;
           }
        }
        return null;
    }
}


public class SpinDemo {
    public static void main(String[] args) throws InterruptedException {
        Integer countryId = ConntryEnum.ONE.getCountryId();
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i <6 ; i++) {
             new Thread(()->{
                 System.out.println(Thread.currentThread().getName()+"被消灭啦");
                 countDownLatch.countDown();//走一个减一
             },ConntryEnum.forConntryEnum(i).getCountryName()).start();
        }
       countDownLatch.await(); //班长等着,啥时候6清0啦 才能走
        System.out.println(Thread.currentThread().getName()+"秦国统一六国");
    }
}


齐被消灭啦
楚被消灭啦
燕被消灭啦
赵被消灭啦
魏国被消灭啦
秦国被消灭啦
main秦国统一六国

CyclicBarrier

CyclicBarrier和CountDownLatch最大的不同是CountDownLatch是倒计时而CyclicBarrier是增加到某个节点的时候,开始程序的运行.

比如: 收集7颗龙珠,召唤神龙

public enum ConntryEnum {
    ONE(0,"一龙珠"),
    TOW(1,"二龙珠"),
    THREE(2,"三龙珠"),
    FOUR(3,"四龙珠"),
    FIVE(4,"五龙珠"),
    SIX(5,"六龙珠"),
    SEVEN(6,"七龙珠");

    private  Integer CountryId;
    private  String CountryName;


    ConntryEnum(Integer countryId, String countryName) {
        CountryId = countryId;
        CountryName = countryName;
    }

    public Integer getCountryId() {
        return CountryId;
    }

    public void setCountryId(Integer countryId) {
        CountryId = countryId;
    }

    public String getCountryName() {
        return CountryName;
    }

    public void setCountryName(String countryName) {
        CountryName = countryName;
    }

    public static ConntryEnum forConntryEnum(int index){
        ConntryEnum[] values = ConntryEnum.values();
        for (ConntryEnum conntryEnum : values){
           if (index== conntryEnum.getCountryId()){
               return conntryEnum;
           }
        }
        return null;
    }
}

public class SpinDemo {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println(Thread.currentThread().getName() + "出来吧神龙");
        }
        );
        for (int i = 0; i <= 6; i++) {
            new Thread(() -> {
                System.out.println("找到了" + Thread.currentThread().getName());
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }, ConntryEnum.forConntryEnum(i).getCountryName()).start();
        }
    }
}

Semaphore

Semaphore主要是解决多个线程抢占多个资源的问题.
比如旅游的时候,只有30个车位,但是此时却有50个人,此时一般情况就是等有人释放啦,排队进行等待.
在这里插入图片描述
构造方法
在这里插入图片描述

public class SpinDemo {
    public static void main(String[] args) throws InterruptedException {
        //3个车位
        Semaphore semaphore = new Semaphore(3);
        //6个人
        for (int i = 0; i <6 ; i++) {
          new Thread(()->{
              try {
                  semaphore.acquire();   // 我抢到一个资源
                  System.out.println(Thread.currentThread().getName()+"抢到车位");
                  Thread.sleep(3000);  //我停车三秒
                  System.out.println(Thread.currentThread().getName()+"释放车位");
              } catch (InterruptedException e) {
                  e.printStackTrace();
              } finally {
                  semaphore.release();//释放车位
              }
          },String.valueOf(i+1)).start();
        }
    }
}

1抢到车位
3抢到车位
2抢到车位
1释放车位
3释放车位
2释放车位
4抢到车位
6抢到车位
5抢到车位
6释放车位
5释放车位
4释放车位
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值