CountDownLatch

CountDownLatch

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

  1. 使用给定计数初始化 CountDownLatch
  2. 由于 countDown() 方法的调用,await 方法阻塞直到当前计数达到零,之后所有等待的线程被释放,并且等待的任何后续调用立即返回。
  3. 这是一次性现象 - 计数无法重置。如果你需要重置计数的版本,请考虑使用 CyclicBarrier

关键方法:

public void await() throws InterruptedException

除非线程被中断,否则导致当前线程等待锁存器倒计数到零。

public void countDown()

减少锁存器的计数,如果计数达到零则释放所有等待的线程。

例:

import java.util.concurrent.*;

class DoSomethingInAThread implements Runnable {
    CountDownLatch latch;
    public DoSomethingInAThread(CountDownLatch latch) {
        this.latch = latch;
    } 
    public void run() {
        try {
            System.out.println("Do some thing");
            latch.countDown();
        } catch(Exception err) {
            err.printStackTrace();
        }
    }
}

public class CountDownLatchDemo {
    public static void main(String[] args) {
        try {
            int numberOfThreads = 5;
            if (args.length < 1) {
                System.out.println("Usage: java CountDownLatchDemo numberOfThreads");
                return;
            }
            try {
                numberOfThreads = Integer.parseInt(args[0]);
            } catch(NumberFormatException ne) {
            
            }
            CountDownLatch latch = new CountDownLatch(numberOfThreads);
            for (int n = 0; n < numberOfThreads; n++) {
                Thread t = new Thread(new DoSomethingInAThread(latch));
                t.start();
            }
            latch.await();
            System.out.println("In Main thread after completion of " + numberOfThreads + " threads");
        } catch(Exception err) {
            err.printStackTrace();
        }
    }
}

输出:

java CountDownLatchDemo 5
Do some thing
Do some thing
Do some thing
Do some thing
Do some thing
In Main thread after completion of 5 threads

说明:

  1. CountDownLatch 在主线程中用计数器 5 初始化
  2. 主线程正在使用 await() 方法等待。
  3. 已经创建了五个 DoSomethingInAThread 实例。每个实例都使用 countDown() 方法递减计数器。
  4. 一旦计数器变为零,主线程将恢复