When a large number of threads are created, degrades the performance of your application. So Java provides a technique of thread pooling to solve this problem.
The thread pooling allows you to reuse a single thread repeatedly instead of creating a new thread for each task and allowing it to be destroyed when the task completes. It avoids the overhead associated with creating a new thread by maintaining a pool of available threads and retrieving one from the pool when necessary.
Now let us consider a program to demonstrate how thread pool is created.
import java.util.concurrent.*; class PrintChar implements Runnable { private char character; private int noOfTimes; PrintChar(char ch, int n) { character = ch ; noOfTimes = n ; } public void run() { for(int i=0; i<noOfTimes; i++) System.out.print(character+" "); } } class Factorial implements Runnable { private int numberLimit; Factorial(int n) { numberLimit = n; } public void run() { for(int i=1; i< numberLimit; i++) System.out.print(fact(i)+" "); } long fact(int num) { if(num==0) return 1; else return(num * fact(num-1)); } } class Threadpool { public static void main(String[] args) { System.out.println("Main Thread starts"); ExecutorService threadExecutor = Executors.newFixedThreadPool(3); PrintChar taskl = new PrintChar('*',50); PrintChar task2 = new PrintChar('S',50); Factorial task3 = new Factorial(10); threadExecutor. execute(taskl); threadExecutor. execute(task2); threadExecutor. execute(task3); threadExecutor.shutdown(); while(! threadExecutor.isTerminated()){} System.out.println("\nMain Thread Ends"); } }
In this program, we have created two classes printChar and Factorial both of which implement the Runnable interface. The PrintChar class contains the code that help to print a character a number of times. The Factorial class contains the code for calculating factorial of numbers ranging from 1 to the number specified.
In main ( ) , the statement
ExecutorService threadExecutor = Executors.newFixedThreadPool(3);
creates a threadpool executer with 3 threads in maximum.
The statement,
PrintChar taskl = new PrintChar(‘*’,50);
creates a Runnable object taskl whose task is to print the character ‘* I 50 times. Similarly, two other Runnable objects task2 and task3 are created whose tasks are to print character’s’ fifty times and print factorial of number ranging from 1 to 10 respectively.
The statement,
threadExecutor.execute(taskl);
creates a new thread inside the ExecutorService to run the Runnable object taskl. Similarly, new threads are created fortask2 and task3 inside the ExecutorService.
The statement,
threadExecutor.shutdown();
tells the threadExecutor to shutdown. No new task can be accepted but the existing task will continue to finish.
In order to ensure that the main thread finishes last i.e. all tasks are finished before the main thread terminates, we put the statement,
while(! threadExecutor.isTerminated()){}