JUC中常用的三種輔助類,你知道嗎?

JUC中提供了三種常用的輔助類,通過這些輔助類可以很好的解決線程數量過多時Lock鎖的頻繁操作。這三種輔助類爲:

  1. CountDownLatch
  2. CyclicBarrier
  3. Semaphore

1.CountDownLatch

下圖是Jdk1.8中解釋的CountDownLatch類功能,簡單而言,在實例化時,需要傳入一個信號量,每當一個線程執行後,信號量減1,當信號量爲0時,釋放阻塞的線程。


不管你聽懂沒,看就完了!

用個小Demo模擬,需求是啓動5個線程,當5個線程執行完後,main線程才能繼續執行,如果不使用CountDownLatch,線程的調用將不可控。

public static void main(final String[] args) throws InterruptedException {
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 執行");
        }, String.valueOf(i)).start();
    }
    System.out.println(Thread.currentThread().getName() + "最終執行");
}


可以看出,不使用任何線程控制等方法,線程是隨計算機調度的,線程的執行順序並不是我們預期希望的。

當使用CountDownLatch,實例化時將信號量設置爲5,每當一個線程執行後,信號量減1,當5個線程執行完後,信號量爲0,main線程才執行。

public static void main(final String[] args) throws InterruptedException {
   //實例化,並傳入信號初始量
    CountDownLatch countDownLatch = new CountDownLatch(5);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t 執行");
            //信號量減1
            countDownLatch.countDown();
        }, String.valueOf(i)).start();
    }
    countDownLatch.await();
    System.out.println(Thread.currentThread().getName() + "最終執行");
}

在這裏插入圖片描述

2.CyclicBarrier

下圖是Jdk1.8中解釋的CyclicBarrier類功能,簡單而言,在實例化時,需要傳入一個信號量和Runnable接口,每當一個線程執行後,信號量加1,當信號量的值達到傳入的預期值,則執行方法。


不管你聽懂沒,看就完了!

這裏我們定義了只要達到3個線程,就執行方法。

public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
        System.out.println("---------方法執行---------");
    });

    for (int i = 0; i < 3; i++) {
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "\t執行");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        }, String.valueOf(i)).start();
    }
}



3. Semaphore(信號燈)

下圖爲Jdk1.8文檔中的解釋,簡單來說,在初始化時設定一個預期值,當線程數量達到預期值,其他線程被阻塞,只有當線程使用完畢,其他線程才能重新開始搶佔資源。

不管你聽懂沒,看就完了!

public static void main(String[] args) {
    Semaphore Semaphore = new Semaphore(3);
    for (int i = 0; i < 5; i++) {
        new Thread(() -> {
            try {
                Semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + "\t搶佔到資源");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() + "\t釋放了資源");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                Semaphore.release();
            }
        }, String.valueOf(i)).start();
    }
}

從運行結果中很容易理解,我們定義了初始值爲3,說明只要有3個線程搶佔到資源,直到他們釋放,其他資源都只能等待。
在這裏插入圖片描述

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