CountDownLatch:等别人做完再继续
适合场景:主线程等多个任务都完成后,再做汇总。
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownLatchDemo { public static void main(String[] args) throws InterruptedException { int taskCount = 3; CountDownLatch latch = new CountDownLatch(taskCount); try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 1; i <= taskCount; i++) { int taskId = i; executor.submit(() -> { try { System.out.println("任务 " + taskId + " 开始执行"); Thread.sleep(1000L * taskId); System.out.println("任务 " + taskId + " 执行完成"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { latch.countDown(); } }); } System.out.println("主线程等待所有任务完成..."); latch.await(); System.out.println("所有任务都完成了,主线程继续执行"); } } }核心记法:
latch.countDown(); // 完成一个,计数减 1 latch.await(); // 等计数变成 0CyclicBarrier:大家到齐再一起继续
适合场景:多个线程都准备好以后,再同时进入下一阶段。
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CyclicBarrierDemo { public static void main(String[] args) { int workerCount = 3; CyclicBarrier barrier = new CyclicBarrier(workerCount, () -> { System.out.println("所有线程都到达栅栏,开始下一阶段"); }); try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { for (int i = 1; i <= workerCount; i++) { int workerId = i; executor.submit(() -> { try { System.out.println("线程 " + workerId + " 正在准备"); Thread.sleep(1000L * workerId); System.out.println("线程 " + workerId + " 到达栅栏"); barrier.await(); System.out.println("线程 " + workerId + " 继续执行后续任务"); } catch (Exception e) { e.printStackTrace(); } }); } } } }核心记法:
barrier.await(); // 到栅栏这里等,直到指定数量的线程都到齐一句话区别:
CountDownLatch:一个线程等多个线程完成。 CyclicBarrier:多个线程互相等,大家到齐再一起走。CountDownLatch一般是一次性的;CyclicBarrier可以循环复用,所以名字里有Cyclic。