Java併發編程系列——CountDownLatch、CyclicBarrier、Semaphore的使用

CountDownLatch

  • 原理:初始化時須要設置一個count變量,await()方法會阻塞當前線程,當其餘線程調用CountDownLatch的countDown()方法的次數等於count時,當前線程被喚醒。
  • 適用場景:可用於等待多個線程完成操做以後,當前線程繼續操做的場景。
public static void main(String[] args) {
    CountDownLatch countDownLatch = new CountDownLatch(3);
    for (int i = 0 ; i < 3 ; i++) {
        int count = i;
        new Thread(() -> {
            System.out.println("Count down thread id : " + count);
            countDownLatch.countDown();
        }).start();
    }
    try {
        System.out.println("Main thread await!");
        countDownLatch.await();
        System.out.println("Main thread finish!");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

從日誌輸出能夠看到,主線程進入等待,當全部子線程均調用了countDown後,主線程繼續執行:java

Main thread await!
Count down thread id : 1
Count down thread id : 0
Count down thread id : 2
Main thread finish!

CyclicBarrier

  • 原理:CyclicBarrier是一道屏障,調用await方法後,當前線程進入阻塞,當parties數量的線程調用await方法後,全部的await方法會返回並繼續往下執行。
  • 適用場景:可用於須要多個線程均到達某一步以後才能繼續往下執行的場景
public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
    for (int i = 0; i < 3; i++) {
        int count = i;
        new Thread(() -> {
            try {
                Thread.sleep(3L);
                System.out.println("Thread id waiting : " + count);
                cyclicBarrier.await();
                System.out.println("Thread id finish : " + count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

從日誌能夠看到,全部線程首先輸出waiting,而後再輸出finish:ui

Thread id waiting : 2
Thread id waiting : 0
Thread id waiting : 1
Thread id finish : 1
Thread id finish : 2
Thread id finish : 0

Semaphore

  • 原理:Semaphore就是信號量,容許特定數量的線程同時執行。調用acquire方法獲取鎖,調用release方法釋放鎖
  • 適用場景:容許特定數量線程同時執行的場景
public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(3);
    for (int i = 0 ; i < 5 ; i++) {
        int count = i;
        new Thread(() -> {
            try {
                semaphore.acquire();
                System.out.println("Thread got semaphore : " + count);
                Thread.sleep(2L);
                semaphore.release();
                System.out.println("Thread release semaphore : " + count);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

從日誌中能夠看出,0、一、2共3個線程首先獲取了鎖,隨後1首先釋放鎖,釋放後3獲取了鎖,獲取鎖的總線程仍爲3。隨後0釋放了鎖,此時4就能夠獲取鎖,執行的總線程仍爲3。線程

Thread got semaphore : 0
Thread got semaphore : 1
Thread got semaphore : 2
Thread release semaphore : 1
Thread got semaphore : 3
Thread release semaphore : 0
Thread got semaphore : 4
Thread release semaphore : 2
Thread release semaphore : 4
Thread release semaphore : 3
相關文章
相關標籤/搜索