所以我们有一个类如下:
public static class BlockMethodtillAnotherCalled {
public void doOnce() {
}
public void blockUntilCall() {
}
}
我们希望实现所有调用blockUntilCall((的线程都将被阻塞,直到调用doOnce((为止。
示例如下:
T1.blockUntilCall->打印输出";。。。现在是块";
T2.blockUntilCall->打印输出";。。。现在是块";
T3.doOnce
T1.blockUntilCall->打印输出";。。。现在发布";
T2.blockUntilCall->打印输出";。。。现在发布";
您应该检查包java.util.concurrent
的描述,特别是名为">同步器";。
同步器
五个类帮助常见的专用同步习惯用法。
Semaphore
是一个经典的并发工具CountDownLatch
是一个非常简单但非常常见的实用程序,用于阻塞,直到给定数量的信号、事件或条件成立CyclicBarrier
是一个可复位的多路同步点,在某些并行编程风格中很有用Phaser
提供了一种更灵活的屏障形式,可以用于控制多个线程之间的分阶段计算Exchanger
允许两个线程在一个集合点交换对象,在几种管道设计中都很有用
在这种情况下,使用从1开始的倒计时,CountDownLatch
是完美匹配。
CountDownLatch
使用给定的计数进行初始化。由于countDown()
方法的调用,await
方法阻塞,直到当前计数达到零,之后释放所有等待的线程,并立即返回任何后续的await
调用。这是一种一次性现象——计数无法重置。如果您需要重置计数的版本,请考虑使用CyclicBarrier
。
以下是CountDownLatch
的javadoc中示例代码的缩小版本,适用于问题中的代码:
public static class BlockMethodtillAnotherCalled {
private CountDownLatch startSignal = new CountDownLatch(1);
public void doOnce() {
this.startSignal.countDown(); // let all threads proceed
}
public void blockUntilCall() {
try {
this.startSignal.await();
} catch (InterruptedException ex) {
// proceed without the start signal
}
}
}