併發專題之--- 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釋放車位
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章