1、CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行;
下面通过一个例子,场景如下:请客吃饭,所有人都到齐了,准备上菜,上菜完成后,开吃。
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
CountDownLatch latch = new CountDownLatch(5);
CyclicBarrier barrier = new CyclicBarrier(5, () -> {
System.out.println("主人说:所有人都上齐了,上菜吧...");
});
// 客人开始从家里出发来饭店吃饭,为了礼貌,所有客人都到了才可以吃饭,所以到了barrier.await之后会阻塞住
for (int j = 0; j < 5; j++) {
int finalJ = j;
service.submit(() -> {
try {
Thread.sleep(new Random().nextInt(5000));
System.out.println("第" + finalJ + "个客人到了,等所有客人都到齐");
//等所有客人都来到才能开始吃饭
barrier.await();
System.out.println("客人" + finalJ + "开始吃饭了");
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
});
}
service.shutdown();
}
2、CountDownLatch,某线程运行到某个点上之后,只是给某个数值-1而已,该线程继续运行。
场景:大家都是好朋友,来吃饭,都是自助,谁来到谁先吃。来到之后,签个到。但是只能所有的客人都来吃完饭,才能清理餐桌,打扫卫生。
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
CountDownLatch latch = new CountDownLatch(5);
// 客人开始从家里出发来饭店吃饭,为了礼貌,所有客人都到了才可以吃饭,所以到了barrier.await之后会阻塞住
for (int j = 0; j < 5; j++) {
int finalJ = j;
service.submit(() -> {
try {
Thread.sleep(new Random().nextInt(5000));
System.out.println("第" + finalJ + "个客人到了");
//来到之后签个到
latch.countDown();
System.out.println("客人" + finalJ + "开始吃饭了");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
try {
//latch.await(5,TimeUnit.HOURS);//等待5个小时,没来的就算了,不等了,收拾东西
latch.await();//一直等
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("所有客人都吃完了,收拾东西");
service.shutdown();
}