[英]How can I tell that threads in ThreadPoolExecutor are done?
我正在编写代码,以确保在提交结果之前,线程池中当前没有任何线程正在运行(为避免丢失数据,我应该将其放入提交中)。 为此,我正在使用:
while (_executor.getActiveCount() > 0)
{
try
{
Thread.sleep(10); // milliseconds
}
catch (InterruptedException e)
{
// OK do nothing
}
}
但是一位同事在评论中指出,getActiveCount的文档指出:
- 返回活跃线程的大概数量
- 执行任务。
因此,在池中仍然有活动线程的情况下,是否存在退出while循环的风险? 如果是这样,等待我所有工作线程完成的正确方法是什么?
编辑:提供更多上下文 :这是一个联机系统,其中包含执行程序服务的任务将无限期运行。 工作通过消息传递系统进入,放置在执行程序中的线程上,不需要任何同步,并且工作进入消息传递系统的另一个队列。 我不想杀死执行程序以等待任务完成。
您可能要考虑使用CompletionService
( http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CompletionService.html )。
CompletionService
包装ExecutorService
并在提交任务时返回Future
。 通过维护这些Future
的列表,您可以查看正在等待的作业是否已经完成。 它还具有其他优势,因为您可以使用某些会计方法,因此可以让其他人使用相同的ExecutorService
,
_executor.awaitTermination();
应该做的工作。 现在,它实际上不会等待线程关闭,而是会等待所有可用任务终止。
您还可以向线程池构造函数提供keepAliveTime
,以立即终止空闲线程:
ExecutorService executor = new ThreadPoolExecutor(0, 10, 0L /* keepAlive */,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
若要通知线程应清除并终止,请使用interrupt方法。 t.interrupt();
并且可以从catch块打印或记录错误日志。
当任务提交给执行者时,它们将返回Future,后者指示它们何时完成。 那是首选的使用机制。
您可以使用JDK ExecutorService关闭/ awaitTermination。
用例:需要在池线程完成后清除线程中的线程局部,这种清除可能需要很长时间(例如,连接关闭)。 之后,主线程才能继续。
工作线程可以在某些集合中注册自己。 为此,覆盖start()
和run()
并将自定义线程工厂传递给ThreadPoolExecutor
:
class MyThreadFactory implements ThreadFactory {
@Override
public Thread newThread(final Runnable r) {
return new MyThread(r);
}
...
class Some {
void waitAllThreads() {
Thread worker;
while ((worker = workerThreads.poll()) != null) {
worker.join();
}
}
...
class MyThread extends Thread {
@Override
public synchronized void start() {
if (getState() == State.NEW) {
some.workerThreads.offer(this);
}
super.start();
}
@Override
public void run() {
try {
super.run();
} finally {
some.workerThreads.remove(this);
}
}
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.