Search code examples
javamultithreadingexecutorservicethreadpoolexecutorforkjoinpool

Java: How to get finished threads to pickup tasks from running threads


I am working on a multithreaded application with tasks that have varying run times. When one thread finishes, is there a way for it to take over some tasks from a still running thread?

Here is an example. I kick off my program with 5 threads, and each have 50 tasks. When the quickest running thread finishes, another thread still has 40 tasks to complete. How can I get the finished thread to take 20 tasks from the other thread, so each continue working on 20 a piece, rather than waiting for the running thread to complete the remaining 40?


Solution

  • Use ForkJoinPool

    A ForkJoinPool differs from other kinds of ExecutorService mainly by virtue of employing work-stealing: all threads in the pool attempt to find and execute subtasks created by other active tasks (eventually blocking waiting for work if none exist). This enables efficient processing when most tasks spawn other subtasks (as do most ForkJoinTasks). When setting asyncMode to true in constructors, ForkJoinPools may also be appropriate for use with event-style tasks that are never joined.

    Java 8 provides one more API in Executors

    static ExecutorService  newWorkStealingPool()
    

    Creates a work-stealing thread pool using all available processors as its target parallelism level.

    ForkJoinPool task stealing

    Have a look at this igvtia article by Ilya Grigorik for more details.

    Have a look at other related java concurrent API @ tutorials like ThreadPoolExecutor, ExecutorService etc.