让我们考虑以下代码:
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cb = new CyclicBarrier(3, () -> {
logger.info("Barrier action starting");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("Barrier action finishing");
});
for (int i = 0; i < 6; i++) {
int counter = i;
Thread.sleep(100);
new Thread(() -> {
try {
logger.info("Try to acquire barrier for {}", counter);
cb.await();
logger.info("barrier acquired for {}", counter);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
我创建了大小 = 3 的屏障和需要 5 秒的屏障动作。
我看到以下输出:
2019-10-27 15:23:09.393 INFO --- [ Thread-0] my.playground.RemoteServiceFacade : Try to acquire barrier for 0
2019-10-27 15:23:09.492 INFO --- [ Thread-1] my.playground.RemoteServiceFacade : Try to acquire barrier for 1
2019-10-27 15:23:09.593 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Try to acquire barrier for 2
2019-10-27 15:23:09.594 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Barrier action starting
2019-10-27 15:23:09.693 INFO --- [ Thread-3] my.playground.RemoteServiceFacade : Try to acquire barrier for 3
2019-10-27 15:23:09.794 INFO --- [ Thread-4] my.playground.RemoteServiceFacade : Try to acquire barrier for 4
2019-10-27 15:23:09.897 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Try to acquire barrier for 5
2019-10-27 15:23:14.594 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Barrier action finishing
2019-10-27 15:23:14.595 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : barrier acquired for 2
2019-10-27 15:23:14.595 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Barrier action starting
2019-10-27 15:23:19.596 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Barrier action finishing
2019-10-27 15:23:19.597 INFO --- [ Thread-0] my.playground.RemoteServiceFacade : barrier acquired for 0
2019-10-27 15:23:19.597 INFO --- [ Thread-4] my.playground.RemoteServiceFacade : barrier acquired for 4
2019-10-27 15:23:19.597 INFO --- [ Thread-3] my.playground.RemoteServiceFacade : barrier acquired for 3
2019-10-27 15:23:19.597 INFO --- [ Thread-1] my.playground.RemoteServiceFacade : barrier acquired for 1
2019-10-27 15:23:19.597 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : barrier acquired for 5
所以我们可以看到:
- 第一次障碍行动持续 15:23:09 - 15:23:14
- 第二个障碍行动持续 15:23:14 - 15:23:19
但在第一次屏障操作终止后,只有一个线程能够记录:
2019-10-27 15:23:14.595 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : barrier acquired for 2
我预计 3 个线程应该能够在大约 15:23:14 获得,因为 CyclicBarrier 大小为 3。
你能解释一下这种行为吗?
附言
我试图运行这段代码很多时间,并且总是得到类似的结果。
PS2。
我试着改变一下时间:
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cb = new CyclicBarrier(3, () -> {
logger.info("Barrier action starting");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("Barrier action finishing");
});
for (int i = 0; i < 6; i++) {
int counter = i;
Thread.sleep(1000);
new Thread(() -> {
try {
logger.info("Try to acquire barrier for {}", counter);
cb.await();
logger.info("barrier acquired for {}", counter);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}
我看到了预期的结果:
2019-10-27 23:22:14.497 INFO --- [ Thread-0] my.playground.RemoteServiceFacade : Try to acquire barrier for 0
2019-10-27 23:22:15.495 INFO --- [ Thread-1] my.playground.RemoteServiceFacade : Try to acquire barrier for 1
2019-10-27 23:22:16.495 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Try to acquire barrier for 2
2019-10-27 23:22:16.496 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Barrier action starting
2019-10-27 23:22:16.998 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : Barrier action finishing
2019-10-27 23:22:16.998 INFO --- [ Thread-0] my.playground.RemoteServiceFacade : barrier acquired for 0
2019-10-27 23:22:16.998 INFO --- [ Thread-2] my.playground.RemoteServiceFacade : barrier acquired for 2
2019-10-27 23:22:16.998 INFO --- [ Thread-1] my.playground.RemoteServiceFacade : barrier acquired for 1
2019-10-27 23:22:17.495 INFO --- [ Thread-3] my.playground.RemoteServiceFacade : Try to acquire barrier for 3
2019-10-27 23:22:18.495 INFO --- [ Thread-4] my.playground.RemoteServiceFacade : Try to acquire barrier for 4
2019-10-27 23:22:19.496 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Try to acquire barrier for 5
2019-10-27 23:22:19.499 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Barrier action starting
2019-10-27 23:22:20.002 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : Barrier action finishing
2019-10-27 23:22:20.003 INFO --- [ Thread-5] my.playground.RemoteServiceFacade : barrier acquired for 5
2019-10-27 23:22:20.003 INFO --- [ Thread-3] my.playground.RemoteServiceFacade : barrier acquired for 3
2019-10-27 23:22:20.003 INFO --- [ Thread-4] my.playground.RemoteServiceFacade : barrier acquired for 4