I have a recursive bulk task that I put into execution in a ForkJoinPool thread pool.
public class SomeTask extends RecursiveAction {
@Override
protected void compute() {
//Some recursive logic...
}
}
public class Main {
public static void main(String[] args) {
startForkJoinPool();
}
private void startForkJoinPool() {
SomeTask someTask = new SomeTask();
ForkJoinPool pool = new ForkJoinPool(4);
pool.invoke(someTask);
pool.shutdown();
}
}
Now I need to execute this logic in two more parallel threads.
I decided to try to use the ExecutorService thread pool, and when I put entities into it for execution, I found out that they are not executed in parallel, but, as it were, one of the threads is parked for the duration of the first one.
public class SomeTask extends RecursiveAction {
@Override
protected void compute() {
//Some recursive logic...
}
}
public class Main {
public static void main(String[] args) {
List<Thread> threadList = new ArrayList<>();
threadList.add(new Thread(() -> startForkJoinPool()));
threadList.add(new Thread(() -> startForkJoinPool()));
ExecutorService executorService = Executors.newFixedThreadPool(2);
threadList.forEach(executorService::execute);
executorService.shutdown();
}
private void startForkJoinPool() {
SomeTask someTask = new SomeTask();
ForkJoinPool pool = new ForkJoinPool(4);
pool.invoke(someTask);
pool.shutdown();
}
}
Tell me, please, what can I do wrong? Many thanks in advance to anyone who can point me in the right direction.
tl;dr
executetosubmit.Executor#executeis not necessarily asyncYou need to carefully read the documentation. This is a tricky area.
The
ExecutorService#executemethod is inherited from the super interfaceExecutor.The Javadoc for
Executorsays:So any
Runnableyou pass toexecutemay or may not be run on a background thread.ExecutorService#submitis always asyncIf you definitely want your
Runnableto run on a background thread, pass toExecutorService#submit.Change this line:
… to this:
Shutdown
Your call to
ExecutorService#shutdownis insufficient. You need to wait for submitted tasks to complete.See the boilerplate method
shutdownAndAwaitTerminationgiven to you in the Javadoc forExecutorService.Or, in Java 19+, call
ExecutorService#close.