一、概述
多线程编程中,在很多情况下,我们会把一个任务分成多个线程去同时执行,以提高效率。
但是我们希望在所有的线程执行完之后,通知主线程,执行的结果。CountDownLatch
可以帮我们完成这一点。
CountDownLatch
允许一个或者多个线程去等待其他线程完成操作。
二、简单示例
笔者就遇到一个需求,需要使用多线程去加载音频文件,然后等待线程
等待所有的音频加载线程
全部加载完之后告知调用者。
CountDownLatch使用示例
public void preload(JSCallback loaded) {
// 创建多线程计数器
CountDownLatch countDownLatch = new CountDownLatch(sourceList.size());
// 使用线程池执行等待任务
executorService.execute(() -> {
try {
// 等待预载成功或超时之后,线程被唤醒
boolean loadResult = countDownLatch.await(LOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if(loadResult){
// 预载成功
MediaInfo mediaInfo = new MediaInfo(defaultTrack().getDuration());
loaded.invoke(PreloadResult.success(mediaInfo));
}else {
// 预载失败
loaded.invoke(PreloadResult.timeout());
}
} catch (InterruptedException e) {
e.printStackTrace();
loaded.invoke(PreloadResult.error("未知错误!"));
}
});
// 预载所有音频轨道
for (int i = 0; i < sourceList.size(); i++) {
Media media = sourceList.get(i);
// 注册预载回调,预载成功会执行一次countDown
preparedEventList[i] = countDownLatch::countDown;
// 开始预载
media.prepared();
}
}
上述示例代码中,音频的加载是异步的。笔者先创建了一个等待线程进行结果的等待,然后启动每一个音频的加载,每一个加载成功会调用countDown
方法。所有的音频加载完之后会唤醒等待线程,此时表示音频已经全部加载完毕。