Thread Pool (TP) maintains a Blocking Queue of tasks and an array of
Threads to run them. Threads from the array keep on dequeing the BQ
(which blocks if its empty) and execute tasks if it has any.
BQ blocks if its full (and can optionally reject too).
why Thread-Pools take 2 arguments : Max no of threads to run and Max
size of BQ
are interfaces to thread-pools and the classes implementing them are
takes a Runnable or Callable and returns a Future.
executor then executes the FutureTask at some point in the future
whose result can be obtained by calling get() in the future object
(Note: If Runnable was submitted, then null is returned).
Future.get() call is blocking and returns only when that task is
of ThreadPools is that they maintain a fixed number of threads in the
pool which do not die after doing one task but switch on to the other
tasks after finishing. Hence, the overhead of creating new Threads
for each task is avoided and this improves performance.
improve performance, one should have one ThreadPoolExecutor if
possible. Having 2 thread-pool-executors in the system may not be
good because if one of the pools’ blocking queue is empty, then
its threads will just lie waiting while the other pool’s
threads may be overworked at that very instant. If there were just
one pool, then all the threads would be working together to give the
executor optionally takes parameters to delay the execution of a
also has parameters to:
task repeatedly at every fixed interval
task repeatedly with fixed delay between each run of the task.
2 tasks’ schedule matures at the same time, then they are run
in FIFO fashion.
is another implementation of ExecutorService whose worker threads
i.e. if a worker thread is idle, it will attempt to share sub-task
from a running thread.
forkJoinPool = new ForkJoinPool ();
masterTask = new HeavyWork (0, end); // where end is a big
HeavyWork is defined below.
see if the pool has any idle worker threads and distributes sub-tasks
among them if any thread is available. If not, it proceeds with
calculation of the task itself.
between Callable and Runnable
interfaces are meant to be used for multi-threading purposes.
is the older interface while Callable was introduced in Java 5.
returns a result and can throw a checked exception but Runnable
cannot do both of these.
mandates implementation of void run ()
mandates implementation of T call () throws Exception
class cannot work with Callable objects.
objects have to be submitted to an executor which returns a Future
object on submission. Future has methods to retrieve the result of
call() after execution.
The fact that Callable can return a result is interesting as it’s
not just a change in the method signature. When multiple threads are
launched to complete a big task, the parent thread might not wait at
the same place i.e. control of execution in parent thread might move
ahead. In such a case, where would the call() method return its
results and where would it throw an exception?
turns out that the executor service maintains the result and
exception thrown per thread.
Future.get() is called, it checks if the corresponding thread has
completed. If yes, then it returns the result (or the exception),
else it blocks till called thread completes.