免费金融网站模板html网站模板免费
在Android开发中,CountDownLatch
和CyclicBarrier
都是用于线程同步的工具类,但设计目的和使用场景有本质区别。以下从核心差异和Android典型场景两方面深入解析:
⚙️ 一、核心区别对比
特性 | CountDownLatch | CyclicBarrier |
---|---|---|
设计目的 | 单向等待:主线程等待子任务完成(1对多) | 多向等待:线程组相互等待到达屏障点(多对多) |
计数器行为 | 一次性(归零后失效) | 可循环使用(自动/手动重置) |
触发机制 | 外部线程调用countDown() 减计数 | 线程主动调用await() ,由最后一个到达的线程触发唤醒 |
异常处理 | 线程中断仅影响自身 | 某线程中断会导致所有等待线程抛出BrokenBarrierException |
回调支持 | ❌ 不支持 | ✅ 支持Runnable barrierAction (屏障点触发后执行) |
一句话总结:
- CountDownLatch:主等子(如司机等乘客到齐发车)
- CyclicBarrier:子等子(如运动员等所有人到起跑线开跑)
📱 二、Android开发中的经典应用场景
1. CountDownLatch:主线程等待异步任务完成
-
场景1:初始化资源聚合
等待多个网络请求/数据库加载完成后更新UI:CountDownLatch latch = new CountDownLatch(3); // 3个子任务// 子任务完成时调用 latch.countDown() loadNetworkData(() -> latch.countDown()); loadDatabase(() -> latch.countDown()); loadLocalFiles(() -> latch.countDown());latch.await(); // 主线程阻塞等待 updateUI(); // 所有资源加载完成后刷新UI
-
场景2:Activity等待多线程预处理
如启动页等待广告加载、用户数据预取完成后跳转主页:// 在SplashActivity中 CountDownLatch initLatch = new CountDownLatch(2); fetchAdConfig(() -> initLatch.countDown()); preloadUserData(() -> initLatch.countDown());if (initLatch.await(3, TimeUnit.SECONDS)) { // 带超时防止死等startActivity(new Intent(this, MainActivity.class)); } else {showError("初始化超时"); }
2. CyclicBarrier:分阶段协同处理数据
-
场景1:多线程分阶段计算
如游戏帧渲染:多个线程分别处理物理、音效、画面,每帧需同步:CyclicBarrier barrier = new CyclicBarrier(3, () -> {Log.d("RENDER", "一帧渲染完成"); // 每帧完成后执行 });executor.execute(() -> {calculatePhysics();barrier.await(); // 等待其他线程renderGraphics(); }); // 其他线程类似
-
场景2:动态重置的同步点
如批量下载任务分批次处理(每批N个文件下载完成后开始压缩):CyclicBarrier batchBarrier = new CyclicBarrier(5, () -> {compressBatchFiles(); // 每5个文件下载完成后压缩 });for (File file : files) {downloadFile(file, () -> batchBarrier.await()); }
⚠️ 三、使用注意事项
问题 | CountDownLatch | CyclicBarrier |
---|---|---|
死锁风险 | 子线程未调用countDown() 导致主线程永久阻塞 → 需设超时await(timeout, unit) | 线程被中断导致屏障损坏 → 需捕获BrokenBarrierException 并重置reset() |
性能开销 | 基于AQS实现,轻量级 | 依赖ReentrantLock,较重(适合低频同步) |
动态调整参与者 | ❌ 初始化后不可变 | ✅ 通过reset() 重置(需处理中断) |
💎 四、总结:Android中的选型建议
场景特征 | 推荐工具 | 示例 |
---|---|---|
主线程等待多个异步任务结果 | CountDownLatch | 启动页聚合初始化任务 |
多线程分阶段执行+重复同步 | CyclicBarrier | 游戏帧同步、批量下载分批次处理 |
需回调通知阶段完成 | CyclicBarrier | 所有线程到达屏障后触发日志/埋点 |
决策树:
- 是否需主线程等待? → 选
CountDownLatch
- 是否需线程组互相等待+多阶段重用? → 选
CyclicBarrier
- 是否需阶段完成回调? → 选
CyclicBarrier
(搭配barrierAction
)
合理选择同步工具,可避免Handler
手工同步的复杂性,提升多线程代码可维护性。在资源初始化、分批次任务等高频场景中,二者能显著简化并发设计。