• creating a new Thread for every job may create performance and memory problems.
  • To overcome this, we should go for Thread pools.
  • Thread pool is a pool of already created Threads ready to do our job.
  • Java 1.5 version introduces Thread pool framework to implement Thread pools.
  • Thread pool framework also known as Executor framework.

we can create a Thread pool as follows

ExecutorService service = Executors.newFixedThreadPool(3);

we can submit a Runnable job by using submit() method service.submit(job);
we can shut down an Executor service by using shutdown() method service.shutdown();

import java.util.concurrent.*;
class PrintJob implements Runnable{
    String name;
    PrintJob(String name){
        this.name = name;
    }
    public void run(){
        System.out.println(name + "...Job started by Threads" + Thread.currentThread().getName());
        try{
            Thread.sleep(2000);
        }
        catch(InterruptedException e){
        }
        System.out.println(name + "...Job completed by Threads:" + Thread.currentThread().getName());
    }
}
class ExecutorDemo{
    public static void main(String[] args){
        PrintJob[] job = {new PrintJob("PK"), new PrintJob("Prabhas"), new PrintJob("NTR"), new PrintJob("MB"), }; 
        ExecutorService service = Executors.newFixedThreadPool(3);
        for(PrintJob jobs : job){
             service.submit(jobs);
        }
        service.shutdown();
    }
}

Output:
PK...Job started by Threadspool-1-thread-1
NTR...Job started by Threadspool-1-thread-3
Prabhas...Job started by Threadspool-1-thread-2
NTR...Job completed by Threads:pool-1-thread-3
PK...Job completed by Threads:pool-1-thread-1
MB...Job started by Threadspool-1-thread-3
Prabhas...Job completed by Threads:pool-1-thread-2
MB...Job completed by Threads:pool-1-thread-3

In the above example 3 threads are responsible to execute 4 jobs so that a single Thread can be reused for multiple jobs.
while developing web servers and application servers we can use ThreadPool concept.

Callable and Future:

In the case Runnable job thread won’t return anything after completing job. If a Thread is required to return some result after executing then we should go for callable.

callable interface contains only one method call().

public Object call() throws Exception

If we submit a Callable Object to Executor then after completing the job Thread returns an Object of the type Future i.e., Future Object can be used to return the result from Callable job.

import java.util.concurrent.*;
    class MyCallable implements Callable{
         int num;
         MyCallable(int num){
             this.num = num;
         }
         public Object call() throws Exception{
             System.out.println(Thread.currentThread().getName() + "is responsible to find sum of first " + num + " numbers");
             int sum = 0;
             for(int i = 1; i <= num; i++){
             sum = sum + i;
             }
             return sum;
        }
}
class CallableFutureDemo{
    public static void main(String[] argsthrows Exception{
        MyCallable[] jobs = {new MyCallable(10), new MyCallable(20), new MyCallable(30), new MyCallable(40), new MyCallable(50)};
        ExecutorService service = Executors.newFixedThreadPool(3);
        for(MyCallable job : jobs){
            Future f = service.submit(job);
            System.out.println(f.get());
        }
        service.shutdown();
    }
}

Output:
pool-1-thread-1 is responsible to find sum of first 10 numbers 55
pool-1-thread-2 is responsible to find sum of first 20 numbers 210
pool-1-thread-3 is responsible to find sum of first 30 numbers 465
pool-1-thread-1 is responsible to find sum of first 40 numbers 820
pool-1-thread-2 is responsible to find sum of first 50 numbers 1275

Difference between Runnable and Callable:

Runnable Callable
If a Thread is not required to return anything after completing the job, then we should go for Runnable If a Thread is required to return something after completing the job, then we should go for Callable
Runnable interface contains one method i.e., run() Callable interface contains one method i.e., call()
Runnable job not required to return anything and hence return type of run() method is void. Callable job required to return something and hence return type of call() method is Object.
Within the run() method if there is any chance of raising checked exception compulsory we should handle by using try-catch because we can’t use throws keyword on run() method Inside call() method if there is any chance of raising checked exception we are not required to handle try-catch because call() method already use throws keyword
Runnable interface present in java.lang package Callable present in java.util.concurrent package
Runnable interface is introduced in 1.0 version Callable interface is introduced in 1.5 version