【问题标题】:ExecutorService specify use new thread for each submitted taskExecutorService 为每个提交的任务指定使用新线程
【发布时间】:2018-02-08 11:00:22
【问题描述】:

我知道 ExecutorService 的目的是回收相同的线程,但在这种情况下,我确实需要为每个提交的任务指定一个新线程。

这里是初始化:

ExecutorService COMMAND_EXECUTOR_SERVICE = Executors.newFixedThreadPool(1);

命令来时:

Task commandExecutionTask = new Task() {
        @Override
        protected Object call() {
            // do something with the command
        }
}

然后:

COMMAND_EXECUTOR_SERVICE.submit(commandExecutionTask);

我怎样才能做到这一点?目的是确保刚刚运行的线程被正确地垃圾收集。

【问题讨论】:

  • 当您的池 (executorservice) 处于活动状态时,线程不会被垃圾收集。执行完任务线程后,如果有新任务,则返回池执行新任务。
  • @user3714601,如果执行程序不保留对线程的任何硬引用。诸如此类的启动和结束线程的问题在其他地方(在系统上下文切换中,这很昂贵)。
  • 虽然ThreadPoolExecutor 允许覆盖execute,但其中引用的一些方法(例如addWorker)以及实例字段(例如workQueue)是私有的,因此使用带有ThreadPoolExecutor 构造函数似乎不是一个选项...
  • @M.Prokhorov,你在说什么?我的意思是,如果不是为了减少池中的线程数,执行程序如何丢失对线程的引用?
  • 您可以通过setCorePoolSize()0 让每个线程在没有更多工作完成时立即终止。但是,我怀疑您希望线程被“垃圾收集”的原因。你能解释一下为什么你认为线程应该“正确收集垃圾”吗?

标签: java multithreading executorservice


【解决方案1】:

我确实需要为每个提交的任务指定一个新线程。”

为什么?

目的是确保刚刚运行的线程被正确收集。

如果你需要关心这个,你就有了一个泄漏的抽象。我能想到的唯一原因是因为您使用的是ThreadLocals,它在任务执行之间保留了价值。

只需在任务中使用具有生命周期的成员变量(例如,在任务内创建的实例的成员变量,而不是保留)。

或者在运行任务结束时添加一些东西以确保ThreadLocal 值被清理,例如

try {
  // Do stuff.
} finally {
  threadLocalVariable.remove();
}

【讨论】:

    【解决方案2】:

    原则上,这很容易。但是,您想要的任务非常具体,并且在各种情况下表现非常糟糕。这就是为什么在 JDK 中没有立即准备好执行此操作的执行器服务的实现(或者至少对外部不可见)。

    要实现这样的执行器,我们需要一个AbstractExecutorService 作为基础,这样我们就不必处​​理管理Futures,而可以专注于执行:

    // If you search JDK, there is a class with this name.
    // That has been taken as a general idea for this one.
    public final class ThreadPerTaskExecutor extends AbstractExecutorService {
      @Override
      public void execute(Runnable task) {
        new Thread(task).start();
      }
    }
    

    我再次建议不要走这条路:在 Java 中盯着Thread,尤其是对于短而便宜的任务,是一个相对昂贵的操作,很容易胜过使用这个类所获得的几乎任何潜在收益。您可能仍想更改外部设计,这样就不需要了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多