如何在提交任何任务之前初始化固定线程池的所有线程? (JAVA)

我正在尝试加速使用ExecutorService并行运行任务的程序.它基本上是这样的:

>初始化大小为n的固定大小的线程池
>阅读包含任务输入的一堆(大约2500个文件)XML文件
>使用池中的工作线程处理XML文件

一切都按预期工作,但我遇到的问题是每个工作线程都有一个类的实例,它对输入数据进行计算.此实例存储在ThreadLocal中.现在,所有这些线程本地实例都是在对应工作线程启动时创建的,这意味着在读取所有XML输入文件之后.

由于计算对象的初始化需要相当长的时间,因此我宁愿让线程池从一开始就初始化所有工作线程,这样计算对象的初始化可以与读取输入文件并行运行.

这里有一些代码可以帮助您了解它当前是如何工作的(我剥离了与问题无关的代码).

初始化线程池和本地线程:

  private final ExecutorService executor = Executors.newFixedThreadPool(Math.max(1, Runtime
      .getRuntime().availableProcessors() - 1));

  private ThreadLocal<Calculator> calculator = new ThreadLocal<Calculator>() {
    @Override
    protected Calculator initialValue() {
      try {
        Calculator instance = createCalculator();
        return instance;
      } catch (Throwable e) {
        throw new RuntimeException(e);
      }
    }
  };

提交新计算:

  @Override
  public FutureTask<Output> calc(Input input) {
    FutureTask<Output> task = new FutureTask<>(
        new Callable<Rueckgabe>() {
          @Override
          public Output call() throws Exception {
            try {
              return calculator.get().calc(input);
            } catch (Throwable e) {
              System.err.println("Exception: " + e.getMessage());
              e.printStackTrace(System.err);
              return null;
            }
          }
        });
    executor.execute(task);
    return task;
  }

让ExecutorService从一开始就为池启动所有工作线程的正确方法是什么?或者我是否需要像虚拟任务那样强制初始化?

PS:由于IT限制,我必须在可预见的未来使用Java 7.

最佳答案
将Threadfactory添加到将执行初始化的Executor.

executor = Executors.newFixedThreadPool(numprocrssors, new ThreadFactory ( ){
    public Thread newThread(Runnable r) {
        return new Thread(r){
            {calculator.get();} // this is an initialization statement, added to all constructors.
        };
    }});

转载注明原文:如何在提交任何任务之前初始化固定线程池的所有线程? (JAVA) - 代码日志