我倾向于CyclicBarrier而且我写了这个演示。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import static java.util.concurrent.ThreadLocalRandom.current;
public class CyclicBarrierDemo {
public static void main(final String[] args) {
final int threads = 100;
final CyclicBarrier barrier
= new CyclicBarrier(threads, () -> System.out.println("tripped"));
final int rounds = 5;
for (int i = 0; i < threads; i++) {
new Thread(() -> {
for (int j = 0; j < rounds; j++) {
try {
Thread.sleep(current().nextLong(1000L));
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace(System.err);
return;
}
}
}).start();
}
}
}
程序会打印五个tripped
并退出,正如我预期的那样。
tripped
tripped
tripped
tripped
tripped
我的问题是CyclicBarrier
实例在最后await()
到达时重置了吗?那么输出是预期的吗?我无法找到任何相关的词语。
答案 0 :(得分:3)
将CyclicBarrier视为门,将汽车视为线程。
闸门(障碍物)在看到100辆汽车在前面等待之前不会打开。当它打开时,它只允许那批100辆汽车通过并再次关闭。同样的事情会发生(循环),它会等待一批100辆汽车再让它们通过。
答案 1 :(得分:2)
我的问题是,当最后一个await()到达时,CyclicBarrier实例会自行重置?
是。从某种意义上说,该实例可以在没有应用程序需要执行某些操作的情况下重用。
这样输出是预期的吗?
是
我无法找到任何关于此的话。
javadoc说:&#34;屏障被称为循环屏障,因为它可以在等待线程释放后重复使用。&#34;
此外,javadoc中显示的示例仅在实例重置自身时才能按描述方式工作。请注意,没有对reset()
的显式调用。 (此外,根据方法&#39; javadoc,如果你想重用一个障碍,那么明确地调用reset()
是不是很有用。)