繁体   English   中英

我怎样才能知道ThreadPoolExecutor中的线程已经完成?

[英]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循环的风险? 如果是这样,等待我所有工作线程完成的正确方法是什么?

编辑:提供更多上下文 :这是一个联机系统,其中包含执行程序服务的任务将无限期运行。 工作通过消息传递系统进入,放置在执行程序中的线程上,不需要任何同步,并且工作进入消息传递系统的另一个队列。 我不想杀死执行程序以等待任务完成。

您可能要考虑使用CompletionServicehttp://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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM