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

时间:2015-08-07 08:54:01

标签: java multithreading threadpool executorservice

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

  1. 初始化大小为n

  2. 的固定大小的线程池
  3. 阅读包含任务输入的一堆(约2500个文件)XML文件

  4. 使用池中的工作线程

  5. 处理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从池中启动所有工作线程的正确方法是什么?或者我是否需要n虚拟任务来强制初始化?

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

1 个答案:

答案 0 :(得分:5)

将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.
        };
    }});