CountDownLatch和CylicBarrier以及Semaphare你使用過嗎

CountDownLatch

是什麼

CountDownLatch的字面意思:倒計時
它的功能是:讓一些線程阻塞直到另外一些線程完成一系列操做後才喚醒。
它經過調用await方法讓線程進入阻塞狀態等待倒計時0時喚醒。
它經過線程調用countDown方法讓倒計時中的計數器減去1,當計數器爲0時,會喚醒哪些由於調用了await而阻塞的線程。多線程

案例

假設老闆開一個緊急會議,他先到會議室等着全部人簽到而後開始開會,可使用CountDownLatch進行模擬。併發

public static void main(String[] args) {
        CountDownLatch countDownLatch=new CountDownLatch(5);

        for (int i=1;i<=5;i++){
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"簽到!");
                countDownLatch.countDown();
            },"第"+i+"個人").start();
        }


        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("老闆宣佈人夠了開始開會!");
    }

運行結果:ui

//注意這裏的簽到順序能夠隨意
第1個人簽到!
第2個人簽到!
第3個人簽到!
第4個人簽到!
第5個人簽到!
老闆宣佈人夠了開始開會!

CyclicBarrier

是什麼

CyclicBarrier [ˈsaɪklɪk] [ˈbæriər] 的字面意思:可循環使用的屏障
它的功能是:讓一組線程到達一個屏障時被阻塞,知道最後一個線程到達屏障,全部被屏障攔截的線程纔會繼續執行。
它經過調用await方法讓線程進入屏障,spa

圖例

例子

仍是上面的開會的例子,咱們使用CyclicBarrier實現。線程

public static void main(String[] args) {
        CyclicBarrier cyclicBarrier=new CyclicBarrier(5,()->{
            System.out.println("老闆宣佈人夠了開始開會!!");
        });

        for (int i=1;i<=5;i++){
            new Thread(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"簽到!");
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },"第"+i+"個人").start();
        }
    }

運行結果:code

第1個人簽到!
第2個人簽到!
第3個人簽到!
第4個人簽到!
第5個人簽到!
老闆宣佈人夠了開始開會!!
  • 假設有個需求要隨機給100個vip會員發邀請短信,若是發完以後發送一個郵件告訴管理員,也可使用這個,並且也能夠利用重置計數的特性再隨機發送100個!

Semaphor

是什麼

Semaphor [ˈseməfɔːr] 信號量的意思;
它主要用於兩個目的:blog

  • 用於多個共享資源互斥使用。
    一個停車場有多個停車位,這多個停車位對應汽車來講就是多個共享資源,Semaphor能夠實現多個停車位和多個汽車之間的互斥。
  • 用於併發線程數的控制。(就是控制同時獲得共享資源的線程數量)
    在建立Semaphor時能夠指定併發線程數,
//permits :容許
    public Semaphore(int permits) {
        sync = new NonfairSync(permits);
    }
    //還能夠指定是否爲公平鎖
    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }
  • 信號量爲1時 至關於獨佔鎖 信號量大於1時至關於共享鎖。

例子

假設如今是年終,總經理和副總經理要求全部部分要進行述職彙報工做,這兩個老總爲了提升效率在辦公室裏決定並行聽取工做,使用Semaphor進行模擬。
根據需求咱們能夠肯定共享資源爲兩個老總,併發彙報工做的最多兩個部門。ip

public static void main(String[] args) {
        Semaphore semaphore=new Semaphore(2);
        for (int i=1;i<=6;i++){
            new Thread(()->{
                try {
                    System.out.println(Thread.currentThread().getName()+"到了辦公室門口,等待述職!");
                    semaphore.acquire();
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName()+"述職中完畢!");
                }
            },"第"+i+"部門").start();
        }
    }

運行效果:資源

第1部門到了辦公室門口,等待述職!
第2部門到了辦公室門口,等待述職!
第3部門到了辦公室門口,等待述職!
第4部門到了辦公室門口,等待述職!
第6部門到了辦公室門口,等待述職!
第5部門到了辦公室門口,等待述職!

第1部門述職中完畢!
第2部門述職中完畢!

第3部門述職中完畢!
第4部門述職中完畢!

第6部門述職中完畢!
第5部門述職中完畢!

注意結果:第1部門和第2部門是同時進行述職的,是兩兩進行的,也就是說咱們控制了多線程狀況下對共享資源訪問時併發線程的數量。get

CountDownlatch和CyclicBarrier以及Semaphor的區別是

  • CountDownLatch是作減法,CyclicBarrier是作加法,Semaphor的臨界資源能夠反覆使用

  • CountDownLatch不能重置計數,CycliBarrier提供的reset()方法能夠重置計數,不過只能等到第一個計數結束。Semaphor能夠重複使用。

  • CountDownLatch和CycliBarrier不能控制併發線程的數量,Semaphor能夠實現控制併發線程的數量。

相關文章
相關標籤/搜索