关键词:Java,线程,线程池,ExecutorService,ThreadPoolExecutor
目标:等待线程池里的子线程正常执行完毕。
方案1(推荐):使用AtomicInteger
类型的计数器,在子线程创建的时候加一,在执行结束的时候减一,主线程等待计数器为零即可。该方案也是ChatGPT给的,实际能满足效果,推荐使用。
首先声明一个AtomicInteger
类型的计数器变量:
protected AtomicInteger taskCount = new AtomicInteger(0); // 线程计数
在创建子线程的时候,构造函数为计数器加一,在执行任务的函数体加上finally
并为计数器减一,这样无论是发生了异常还是正常结束计数器都能正确减一。
private class DirectoryRunner implements Runnable {
private File dir;
public DirectoryRunner(File dir) {
taskCount.incrementAndGet(); // 计数器加一
this.dir = dir;
}
public void run() {
try {
//...
} catch (Exception e) {
e.printStackTrace();
} finally {
taskCount.decrementAndGet(); // 计数器减一
}
}
}
主线程中等待所有子线程正常结束:
// 等待所有动态创建的子线程结束
try {
while (taskCount.get() > 0 && isFinding) {
Thread.sleep(1000); // 等待所有任务完成
}
isFinding = false;
} catch (InterruptedException e) {
//e.printStackTrace();
}
// 通知UI扫描结束
if (fileFindListener != null) {
ThreadUtil.runOnUi(new Runnable() {
@Override
public void run() {
fileFindListener.onFindComplete(foundFiles);
}
});
}
方案2:使用ThreadPoolExecutor
的getActiveCount
来判断是否还有活动线程,如果没有则认为子线程全部结束了。
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 2);
if (!executor.isShutdown()) {
executor.execute(new XXXXXRunner(arg));
}
try {
ThreadPoolExecutor pool = (ThreadPoolExecutor) this.executor;
int activeThreadCnt = 0;
do {
this.executor.awaitTermination(1, TimeUnit.SECONDS);
activeThreadCnt = pool.getActiveCount();
} while (activeThreadCnt > 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
经实际测试该方案效果不理想,仍然达不到预期,请使用推荐方案。
文档信息
- 本文作者:zhupite
- 本文链接:https://zhupite.com/android/java-wait-all-thread-done.html
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)