ExecutorService为每个提交的任务指定使用新线程

时间:2018-02-08 11:00:22

标签: java multithreading executorservice

我知道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);

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

2 个答案:

答案 0 :(得分:1)

  

我真的需要为每个提交的任务指定使用新线程。"

为什么?

  

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

如果您需要关心这一点,那么您就会出现漏洞。我能想到的唯一原因是因为你正在使用ThreadLocal,它们保留了任务执行之间的价值。

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

或者在运行任务结束时添加一些内容,以确保清除ThreadLocal值,例如

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

答案 1 :(得分:0)

这原则上很容易。但是,您希望这样做的任务非常具体,并且在广泛的情况下表现非常糟糕。这就是为什么在JDK中没有立即执行执行器服务的原因(或者至少不是外部可见的)。

要实现这样的执行程序,我们需要AbstractExecutorService作为基础,因此我们不必处理管理Future,并且可以专注于执行:

// 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,特别是对于简短而便宜的任务,这是一项相对昂贵的操作,很容易胜过使用这门课程所带来的任何潜在收益。您可能仍希望更改外部设计,因此您不需要这样做。