Using ExecutorService to repeatedly perform a number of similar tasks in parallel
concurrency, executorservice, java, multithreading
Solution
`Executors.newSingleThreadExecutor()` will create only a single thread. What you want is `Executors.newFixedThreadPool(3)`. Call this before the while loop, so the threads are only created once.
Create a Callable wrapper:
class MyCallable implements Callable<V> {
P p;
MyCallable(P parameter) {
p = parameter;
}
V call() {
return CalcResult(p);
}
}
while loop:
ExecutorService executor = Executors.newFixedThreadPool(3);
while (cond) {
Future<V> aFuture = executor.submit(new MyCallable(param1));
Future<V> bFuture = executor.submit(new MyCallable(param2));
Future<V> cFuture = executor.submit(new MyCallable(param3));
// this will block until all calculations are finished:
a = aFuture.get();
b = bFuture.get();
c = cFuture.get();
// do something with a/b/c, e.g. calc new params.
}
Problem
There is Java code which when simplified looks like this: ``` while(someCondition) { SomeType a = CalcResult(param1); SomeType b = CalcResult(param2); SomeType c = CalcResult(param3); // Do something with a, b and c } ``` `CalcResult()` is time consuming. The application runs on an SMP system. There is a push to try running all three calculations simultaneously each on its own CPU instead of running them sequentially. It is always those 3 tasks that need to be parallel, not an arbitrary number of tasks (such is the algorithm). Each task may take slightly more or less time than others, but generally the variances are not so large (20-30%). As they need to return a result, I looked at the Executor service solutions such as this from https://stackoverflow.com/a/9148992/2721750: ``` ExecutorService executor = Executors.newSingleThreadExecutor(); Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() { return 2; } }; Future<Integer> future = executor.submit(callable); // future.get() returns 2 executor.shutdown(); ``` As my experience with Java is mainly in servlet/JSP development I have no experience with threads and not sure if that snippet would work with 3 tasks instead of one. How can I submit 3 tasks, each with its own parameter value, and wait untill all of them return the result of calculation, simultaneously making sure that creating threads for them does not negate the advantage of running on their own CPUs, i.e. is there a way to create the threads once before the `while()` loop strarts, then simply shove a new `paramN` into each of the threads inside the loop, waking them up, and wait until they performed all of the calculations?