1. 程式人生 > >執行緒同步工具CountDownLatch的使用

執行緒同步工具CountDownLatch的使用

CountDownLatch 用法

CountDownLatch是java.util.concurrent包中一個類,CountDownLatch只要提供的機制是多個(具體數量等於初始化CountDownLatch時count的值)執行緒都達到了預期狀態或者完成了預期工作時觸發事件,其他執行緒可以等待這個事件來觸發自己後續的工作。等待的執行緒可以是多個,即CountDownLatch可以喚醒多個等待的執行緒。到達自己預期狀態的執行緒會呼叫CountDownLatch的countDown方法,而等待的執行緒會呼叫CountDownLatch的await方法。 這裡寫圖片描述

結合以下幾個例子,可以快速掌握這個這個類的基本使用方法: 例一:

public static void main(String[] args) throws InterruptedException {
    CountDownLatch countDown = new CountDownLatch(1);
        CountDownLatch await = new CountDownLatch(5);

        // 依次建立並啟動處於等待狀態的5個MyRunnable執行緒
        for (int i = 0; i < 5; ++i) {
            new Thread(new MyRunnable(countDown, await
)).start(); } System.out.println("用於觸發處於等待狀態的執行緒開始工作......"); System.out.println("用於觸發處於等待狀態的執行緒工作完成,等待狀態執行緒開始工作......"); countDown.countDown(); await.await(); System.out.println("Bingo!"); } public class MyRunnable implements Runnable { private
final CountDownLatch countDown; private final CountDownLatch await; public MyRunnable(CountDownLatch countDown, CountDownLatch await) { this.countDown = countDown; this.await = await; } public void run() { try { countDown.await();//等待主執行緒執行完畢,獲得開始執行訊號... System.out.println("處於等待的執行緒開始自己預期工作......"); await.countDown();//完成預期工作,發出完成訊號... } catch (InterruptedException e) { e.printStackTrace(); } } } 執行結果: 用於觸發處於等待狀態的執行緒開始工作...... 用於觸發處於等待狀態的執行緒工作完成,等待狀態執行緒開始工作...... 處於等待的執行緒開始自己預期工作...... 處於等待的執行緒開始自己預期工作...... 處於等待的執行緒開始自己預期工作...... 處於等待的執行緒開始自己預期工作...... 處於等待的執行緒開始自己預期工作...... Bingo!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

例子二:

public class TestDemo2 {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5));
        int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);

        for (int i = 0; i < count; i++) {
            threadPool.execute(new MyRunnable1(latch, i));
        }

        latch.await();
        System.err.println("等待執行緒被喚醒!");
        threadPool.shutdown();
    }
}

class MyRunnable1 implements Runnable {

    CountDownLatch latch = null;
    int i;

    public MyRunnable1(CountDownLatch latch, int i) {
        this.latch = latch;
        this.i = i;
    }

    @Override
    public void run() {
        System.err.println("執行緒" + i +"完成了操作...");
        try {
            Thread.currentThread();
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }

}
執行結果:
執行緒0完成了操作...
執行緒3完成了操作...
執行緒2完成了操作...
執行緒1完成了操作...
執行緒4完成了操作...//暫停4秒
執行緒5完成了操作...
執行緒6完成了操作...
執行緒8完成了操作...
執行緒7完成了操作...
執行緒9完成了操作...//暫停4秒
等待執行緒被喚醒!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52