-
Notifications
You must be signed in to change notification settings - Fork 0
Home
ForkJoinPool breaks down a big task into smaller subtasks, which can then be executed in parallel.
These subtasks are executed by different threads, and since threads can run on different CPUs, tasks get completed faster with better parallelism.

In some cases, it is useful to run multiple tasks on the same CPU.
For example, if a task performs blocking IO, then while one thread is waiting on IO, another thread can switch to a different task.
Even if all threads are performing blocking IO, they usually don’t block at the same time.
This way, ForkJoinPool helps us to keep CPUs busy and improve overall utilization.
In ForkJoinPool,** a task is divided into subtasks**, and each subtask can further be divided into even smaller subtasks.

This approach is very effective for solving problems using the divide-and-conquer strategy. It mainly works in two phases: Fork Phase
In this phase, the original task is split into multiple subtasks.
Each subtask can again be divided recursively until the task becomes small enough to be executed directly.
This recursive splitting ensures that large and complex tasks are broken down into smaller, manageable units.
Join Phase
Once the subtasks are completed, their results are combined (joined).
This process continues recursively until the final result is produced and returned to the main task.

The ForkJoinPool also uses a work-stealing algorithm. This means if one thread finishes its work early, it can "steal" pending tasks from other threads’ queues, which ensures better load balancing. Because of this mechanism, ForkJoinPool helps us to utilize the CPU more efficiently. Even if some tasks are waiting due to blocking IO, other threads can continue executing different tasks, so the CPU does not remain idle. This makes ForkJoinPool highly useful for tasks like **parallel computations, recursive algorithms (e.g., merge sort, matrix multiplication), or processing large data **sets where tasks can naturally be divided into smaller pieces. Work Stealing in ForkJoinPool Suppose we have 2 threads in a ForkJoinPool, and each thread has 3 tasks. In Thread 1’s queue, one task (red) takes much longer, and two other tasks (yellow) are waiting.
In Thread 2’s queue, all 3 tasks are shorter, so Thread 2 finishes quickly and becomes idle, while Thread 1 is still busy with the long red task and has 2 yellow tasks waiting.

Here comes the work stealing algorithm: Instead of keeping Thread 2 idle, it can **steal tasks **from the queue of Thread 1.
So Thread 2 can pick up the yellow tasks from Thread 1’s queue and start processing them in parallel. This way, both threads keep working, and the overall completion time is reduced. If there is only one CPU, work stealing might not bring much benefit, because tasks are still executed sequentially on a single core. But with multiple CPUs, it becomes very effective since multiple tasks can really run in parallel. On some modern CPUs, there are **performance cores **(fast but power-hungry) and efficiency cores (slower but energy-saving). If Thread 2 runs on an efficiency core, it may process the stolen task slower than a performance core, but still it is better than leaving that core idle. This ensures that all CPU resources are used, balancing performance and efficiency.