天天看點

【并發】CountDownLatch使用一、參考二、介紹三、個人demo

目錄

  • 一、參考
  • 二、介紹
  • 三、個人demo
    • 1.用法一:一個線程等待其他多個線程都執行完畢,再繼續自己的工作
    • 2.用法二:多個線程等待某一個線程的信号,同時開始執行

一、參考

  1. 【線程】并發流程控制的同步工具-CountDownLatch

二、介紹

CountDownLatch是一種并發流程控制的同步工具。

主要的作用是等待一個或多個線程完成任務之後,再繼續完成其他線程的任務。

用法:

  1. 初始化
初始化時需要給定一個

count

值。
  1. countDown()方法
該方法的作用是使

count

值-1,當

count

值減到0時會釋放所有等待狀态中的其他線程。
  1. await()方法
讓目前線程等待,直到

count

值變成0。可以設定等待時間。
countDownLatch.await();
//或
countDownLatch.await(5, TimeUnit.SECONDS);
           

三、個人demo

1.用法一:一個線程等待其他多個線程都執行完畢,再繼續自己的工作

/**
 * CountDownLatch
 * 用法一:一個線程(這裡指main主線程)等待其他多個線程都執行完畢,再繼續自己的工作
 *
 * @author
 * @createTime 2022/10/18 10:19 上午
 **/
public class CountDownLatchTest1 {

    private static ReentrantLock lock = new ReentrantLock();

    private static CountDownLatch countDownLatch = new CountDownLatch(4);

    /**
     * 這裡模拟的是等所有人到齊之後就開車出發
     * @param args
     */
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        IntStream.range(0, 4).forEach(value -> {
            executorService.submit(() -> {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + "準備去坐車");
                    Thread.sleep(1000);
                    countDownLatch.countDown();
                    System.out.println(Thread.currentThread().getName() + " 坐上車了!");
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            });
        });

        try {
            countDownLatch.await(5, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName() + "-人到齊了,出發!");
            executorService.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
           

運作結果:

pool-1-thread-4準備去坐車
pool-1-thread-4 坐上車了!
pool-1-thread-3準備去坐車
pool-1-thread-3 坐上車了!
pool-1-thread-2準備去坐車
pool-1-thread-2 坐上車了!
pool-1-thread-1準備去坐車
pool-1-thread-1 坐上車了!
main-人到齊了,出發!
           

2.用法二:多個線程等待某一個線程的信号,同時開始執行

/**
 * CountDownLatch
 * 用法二:多個線程等待某一個線程(這裡指main主線程)的信号,同時開始執行
 *
 * @author
 * @createTime 2022/10/18 10:40 上午
 **/
public class CountDownLatchTest2 {

    private static ReentrantLock lock = new ReentrantLock();

    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 這裡模拟的是3s後再讓排隊的所有人上車
     * @param args
     */
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        IntStream.range(0, 4).forEach(value -> {
            executorService.submit(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + "排隊中...");
                    countDownLatch.await();
                    System.out.println(Thread.currentThread().getName() + "上車了!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        });

        try {
            System.out.println(Thread.currentThread().getName()+ "- 3s後所有人開始上車");
            Thread.sleep(3000);
            countDownLatch.countDown();//釋放信号量
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
           

運作結果:

main- 3s後所有人開始上車
pool-1-thread-4排隊中...
pool-1-thread-1排隊中...
pool-1-thread-3排隊中...
pool-1-thread-2排隊中...
pool-1-thread-4上車了!
pool-1-thread-2上車了!
pool-1-thread-3上車了!
pool-1-thread-1上車了!