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?
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.
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.