Java多線程與併發_同步工具類CountDownLatch,CyclicBarrier和Semaphore

Java多線程與併發_同步工具類CountDownLatch,CyclicBarrier和Semaphore

人處在一種默默奮鬥的狀態,精神就會從瑣碎生活中得到昇華

一、CountDownLatch

構造器

  • CountDownLatch(int count) //參數count爲計數值

主要方法:

  • await():調用await()方法的線程會被掛起,它會等待直到count值爲0才繼續執行
  • await(long timeout,TimeUnit unit):和await()類似,只不過等待一定的時間後count值還沒變爲0的話就會繼續執行
  • countDown():將count值減1

例子說明:秦滅6國,一統華夏

  • 解釋:6個國家陸續被滅後,秦國最後才一統華夏
  • main主線程必須要等前面6個線程完成全部工作後,自己才能開幹
public class CountDownLatchDemo {

    public static void main(String[] args) throws InterruptedException {
        //秦滅6國,一統華夏
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 國被滅");
                countDownLatch.countDown();
            },CountryEnums.forEachCountryEnums(i).getRetMsg()).start();
        }
        countDownLatch.await();

        System.out.println("-------main 秦滅6國,一統華夏");
    }
}

國家的枚舉類

public enum CountryEnums {
    ONE(0,"韓"),
    TWO(1,"魏"),
    THREE(2,"趙"),
    FOUR(3,"齊"),
    FIVE(4,"楚"),
    SIX(5,"燕")
    ;

    private Integer retCode;
    private String retMsg;

    CountryEnums(Integer retCode, String retMsg) {
        this.retCode = retCode;
        this.retMsg = retMsg;
    }

    public Integer getRetCode() {
        return retCode;
    }

    public void setRetCode(Integer retCode) {
        this.retCode = retCode;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public static CountryEnums forEachCountryEnums(Integer index) {
        for (CountryEnums element : values()) {
            if (element.getRetCode() == index) {
                return element;
            }
        }
        return null;
    }
}

結果

韓	 國被滅
齊	 國被滅
趙	 國被滅
魏	 國被滅
楚	 國被滅
燕	 國被滅
-------main 秦滅6國,一統華夏

Process finished with exit code 0

二、CyclicBarrier

字面意思是可循環(Cyclic)使用的屏障(Barrier),他要做的事情是,
讓一組線程到達一個屏障(也可以叫同步點)時被阻塞,
直到最後一個線程到達屏障時,屏障纔會開門,所有被屏障攔截的線程纔會繼續幹活。
線程進入屏障通過CyclicBarrier的await()方法

構造器

  • CyclicBarrier(int parties, Runnable barrierAction)
  • CyclicBarrier(int parties)

參數parties指讓多少個線程或者任務等待至barrier狀態;參數barrierAction爲當這些線程都達到barrier狀態時會執行的內容。

主要方法

  • int await()
  • int await(long timeout, TimeUnit unit)

第一個版本比較常用,用來掛起當前線程,直至所有線程都到達barrier狀態再同時執行後續任務;

第二個版本是讓這些線程等待至一定的時間,如果還有線程沒有到達barrier狀態就直接讓到達barrier的線程執行後續任務。

例子說明:集齊7顆龍珠召喚神龍

public class CyclicBarrierDemo {

    private static final int NUMBER = 7;

    public static void main(String[] args) {

        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUMBER,() -> {
            System.out.println("*****召喚神龍*****");
        });

        for (int i = 1; i <= NUMBER; i++) {
            int tempInt = i;
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 收集到第" + tempInt + "\t 顆龍珠");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

結果

1	 收集到第1	 顆龍珠
4	 收集到第4	 顆龍珠
3	 收集到第3	 顆龍珠
2	 收集到第2	 顆龍珠
5	 收集到第5	 顆龍珠
6	 收集到第6	 顆龍珠
7	 收集到第7	 顆龍珠
*****召喚神龍*****

Process finished with exit code 0

三、Semaphore

Semaphore(信號量)是用來控制同時訪問特定資源的線程數量,它通過協調各個線程,以保證合理的使用公共資源。

public class SemaphoreDemo {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);//模擬3個停車位

        for (int i = 1; i <= 6; i++) {//模擬6部汽車
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t 搶佔了車位");
                    TimeUnit.SECONDS.sleep(new Random().nextInt(8));
                    System.out.println(Thread.currentThread().getName() + "\t 離開了車位");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

結果:

1	 搶佔了車位
3	 搶佔了車位
2	 搶佔了車位
2	 離開了車位
3	 離開了車位
4	 搶佔了車位
5	 搶佔了車位
1	 離開了車位
6	 搶佔了車位
4	 離開了車位
5	 離開了車位
6	 離開了車位

Process finished with exit code 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章