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() { ... }
}