Java|CountDownLatch

CountDownLatch 是一个线程栓子,当计数到达 0 释放所有线程运行,它只能使用一次,CyclicBarrier 可以使用多次。

示例一

public class CountDownLatchUtil {
    private CountDownLatch start;
    private CountDownLatch end;
    private int poolSize;

    public CountDownLatchUtil() {
        this(10);
    }

    public CountDownLatchUtil(int poolSize) {
        this.poolSize = poolSize;
        start = new CountDownLatch(1);
        end = new CountDownLatch(poolSize);
    }

    public void latch(MyFunctionalInterface functionalInterface) throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(poolSize);
        for (int i = 0; i < poolSize; i++) {
            Runnable runnable = new Runnable() {

                @Override
                public void run() {
                    try {
                        start.await();
                        functionalInterface.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        end.countDown();
                    }
                }
            };
            service.execute(runnable);
        }
        // start all task
        start.countDown();
        // wait until all task finish
        end.await();
    }

    @FunctionalInterface
    public interface MyFunctionalInterface {
        void run();
    }
}

示例二

  class Driver { // ...
    void main() throws InterruptedException {
      CountDownLatch startSignal = new CountDownLatch(1);
      CountDownLatch doneSignal = new CountDownLatch(N);

      for (int i = 0; i < N; ++i) // create and start threads
        new Thread(new Worker(startSignal, doneSignal)).start();

      doSomethingElse();            // don't let run yet
      startSignal.countDown();      // let all threads proceed
      doSomethingElse();
      doneSignal.await();           // wait for all to finish
    }
  }

  class Worker implements Runnable {
    private final CountDownLatch startSignal;
    private final CountDownLatch doneSignal;
    Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
      this.startSignal = startSignal;
      this.doneSignal = doneSignal;
    }
    public void run() {
      try {
        startSignal.await();
        doWork();
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
    }

    void doWork() { ... }
  }

示例三

  class Driver2 { // ...
    void main() throws InterruptedException {
      CountDownLatch doneSignal = new CountDownLatch(N);
      Executor e = ...

      for (int i = 0; i < N; ++i) // create and start threads
        e.execute(new WorkerRunnable(doneSignal, i));

      doneSignal.await();           // wait for all to finish
    }
  }

  class WorkerRunnable implements Runnable {
    private final CountDownLatch doneSignal;
    private final int i;
    WorkerRunnable(CountDownLatch doneSignal, int i) {
      this.doneSignal = doneSignal;
      this.i = i;
    }
    public void run() {
      try {
        doWork(i);
        doneSignal.countDown();
      } catch (InterruptedException ex) {} // return;
    }

    void doWork() { ... }
  }