Java如何启动多线程执行固件更新并等待全部任务完成后再继续
多设备固件更新等待所有任务完成的可靠实现方案
方案1:使用CountDownLatch实现阻塞等待
该工具类专门适配「主线程等待一批子任务全部执行完成」的场景,完全匹配你的需求,实现逻辑如下:
- 初始化
CountDownLatch实例,计数设置为需要更新的设备总数量 - 每个固件更新线程的任务逻辑中,不管更新成功还是失败,都要在任务执行结束的
finally块中调用countDown()方法,将计数减1 - 主线程启动所有更新线程后,调用
await()方法进入阻塞状态,直到CountDownLatch的计数降到0,代表所有更新任务都已执行完成,再继续执行后续的服务器重启逻辑
参考实现代码:
// 按实际设备数量设置计数 int deviceTotal = 15; CountDownLatch updateFinishLatch = new CountDownLatch(deviceTotal); // 保留你原有用来控制任务同时启动的CyclicBarrier CyclicBarrier startBarrier = new CyclicBarrier(deviceTotal); for (int i = 0; i < deviceTotal; i++) { new Thread(() -> { try { startBarrier.await(); // 所有线程就绪后同时启动更新 // 原有固件更新逻辑 Process updateProcess = new ProcessBuilder("你的固件更新命令").start(); int exitCode = updateProcess.waitFor(); // 按需处理更新返回结果 } catch (Exception e) { // 记录错误日志,标记对应设备更新失败 } finally { // 确保无论任务是否异常,都能触发计数减1 updateFinishLatch.countDown(); } }).start(); } // 主线程阻塞等待所有更新任务完成,建议设置超时避免无限等待 updateFinishLatch.await(20, TimeUnit.MINUTES); // 所有任务完成后再执行后续重启逻辑
方案2:使用线程池内置等待机制
如果你用线程池管理更新线程,可以直接用线程池的原生方法实现等待:
- 把所有固件更新任务封装为
Callable实例,统一提交给ExecutorService线程池 - 调用
invokeAll()方法,该方法会直接阻塞,直到所有提交的任务都执行完成,返回所有任务的执行结果列表 - 也可以在提交完所有任务后调用线程池的
shutdown()方法,再调用awaitTermination()设置超时时间等待所有任务执行结束
注意事项
- 必须给等待操作设置合理的超时时间,避免个别设备更新卡住导致整个流程无限阻塞,超时后触发告警,单独处理未完成更新的设备,不要直接执行重启
- 每个更新任务要做好异常捕获和结果记录,最后统计更新成功、失败的设备列表,失败的设备不要加入后续重启队列,避免设备损坏
内容的提问来源于stack exchange,提问作者Korlimann
相关产品推荐
相关产品推荐

