I am bit confused how Forkjoin internally works vs Thread Pool. Below is the code snippet for the same. Both are having single parallelism. Ideally it should behave same as Thread pool and it should not pick the task unless it finishes.
public class Sample {
public static void main(String[] args) {
// Use either ThreadPoolExecutor or ForkJoin.
//ThreadPoolExecutor pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
ForkJoinPool pool = new ForkJoinPool(1);
List<Integer> items = new ArrayList<>();
items.add(1);
items.add(2);
// Create 2 task and submit to thread pool. Wait for it to execute all the task.
pool.submit(() -> {
try {
startProcessing(items.get(0));
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
pool.submit(() -> {
try {
startProcessing(items.get(1));
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
pool.shutdown();
pool.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void startProcessing(int itemVal) throws ExecutionException, InterruptedException {
doProcessing(itemVal).get();
System.out.println("Ended :" + itemVal);
}
private static CompletableFuture<Integer> doProcessing(int itemVal) throws InterruptedException {
CompletableFuture<Integer> future = new CompletableFuture<>();
System.out.println("Started :" + itemVal);
// I was assuming as this is waiting for child thread to also complete,
// so this thread will be waiting and hence will be waiting for task 1 untill it finishes.
// BUT IT GOT CONTEXT SWITCHED AND PICKED THE TASK 2.
asyncCall(future, itemVal);
return future;
}
// This is the place where new thread is created.
private static void asyncCall(CompletableFuture<Integer> future, int itemVal) {
Thread t = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
future.complete(itemVal);
});
t.start();
}
}
Below is the output if using Thread pool:
Started :1
Ended :1
Started :2
Ended :2
And below is the output if using Fork Join:
Started :1
Started :2
Ended :1
Ended :2
Why is this difference in behavior for Fork Join compared to thread pool?