CountDownLatch 的线程协调完全基于 AQS 的 CAS 和队列机制,不依赖 synchronized;其 await() 和 countDown() 均通过原子操作实现,synchronized 仅在业务层保护共享资源时可选使用。
java中 synchronized 本身并不参与 countdownlatch 的核心协同逻辑,两者职责不同、机制独立。countdownlatch 的线程等待与唤醒完全基于 aqs(abstractqueuedsynchronizer)的共享锁机制,无需、也不依赖 synchronized 实现同步。
CountDownLatch 自身不使用 synchronized
CountDownLatch 的关键操作——await() 和 countDown()——全部通过 CAS 原子操作和 AQS 队列管理实现:
-
countDown()调用releaseShared(1),底层使用 CAS 修改 AQS 的state字段,无锁竞争 -
await()调用acquireSharedInterruptibly(1),若计数未归零,则将当前线程安全入队并挂起,不靠synchronized阻塞 - 所有状态变更和线程调度均由 AQS 保证线程安全,无需额外加锁
何时可能在配合使用中见到 synchronized
开发者有时会在使用 CountDownLatch 的业务代码里自行添加 synchronized,但这属于外围保护,与 CountDownLatch 协同无关:
- 多个线程调用
countDown()时,若其内部还修改了共享对象(如汇总结果列表),需对共享资源加锁,防止并发写异常 - 主线程在
await()返回后读取多线程计算结果,若结果被非线程安全容器(如ArrayList)收集,写入阶段可能需要synchronized或改用CopyOnWriteArrayList - 错误示例:试图用
synchronized(latch)控制await()或countDown()调用顺序——既无必要,也无效,因为 CountDownLatch 不依赖对象监视器
替代 synchronized 的更合理做法
在 CountDownLatch 场景中,优先选择与并发模型匹配的线程安全机制:
- 共享状态更新:用
AtomicInteger、AtomicReference替代synchronized块 - 集合操作:选用
ConcurrentHashMap、CopyOnWriteArrayList等并发集合 - 任务协调:信任 CountDownLatch 本身的 AQS 保障,专注业务逻辑拆分与结果聚合
CountDownLatch 是轻量、高效、一次性的协作工具;synchronized 是重量级监视器锁,用于临界区互斥。混用不是设计需求,而是特定业务下对共享数据的额外保护——理清边界,才能用得准确。
立即学习“Java免费学习笔记(深入)”;


















