How to initialize all threads of a fixed thread pool before sending any tasks? (JAVA)

I am trying to speed up a program that uses ExecutorService to run tasks in parallel. It basically works as follows:

  • Initialize a fixed-size thread pool of size n

  • Read a bunch (about 2500 files) of XML files containing input for tasks

  • Process XML files using workflows from the pool

Everything works as expected, but the problem is that each worker thread has an instance of a class that performs calculations on the input. This instance is stored in ThreadLocal . Now all these local stream instances are created when the correspondent workflow starts, which means that after reading all the input XML files.

Since initialization of calculation objects takes quite a lot of time, I would prefer the thread pool to initialize all workflows from the very beginning, so that initialization of calculation objects can be performed in parallel with reading the input files.

Here is some code to help you understand how it works at the moment (I deleted the code that is not related to the problem).

Initializing the thread pool and local thread:

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

Sending a new calculation:

  @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; } 

What is the correct way to run ExecutorService all worker threads for a pool from the start? Or do I need something like n dummy tasks to force initialization?

PS: I have to use Java 7 for the foreseeable future due to IT limitations.

+4
source share
1 answer

Add Threadfactory for the Contractor who will perform the initialization.

 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. }; }}); 
+4
source

All Articles