Java Concurrency Tutorial: Thread Pools
Instead of starting a new thread for every task to execute concurrently, the task can be passed to a thread pool. As soon as the pool has any idle threads the task is assigned to one of them and executed. Internally the tasks are inserted into a Blocking Queue which the threads in the pool are dequeuing from. When a new task is inserted into the queue one of the idle threads will dequeue it successfully and execute it. The rest of the idle threads in the pool will be blocked waiting to dequeue tasks.
Thread pools are often used in multi threaded servers. Each connection arriving at the server via the network is wrapped as a task and passed on to a thread pool. The threads in the thread pool will process the requests on the connections concurrently. A later trail will get into detail about implementing multithreaded servers in Java.
Java 5 comes with built in thread pools in the java.util.concurrent package, so you don't
have to implement your own thread pool. Still it can be useful to know a bit about the implementation
of a thread pool anyways.
Here is a simple thread pool implementation:
public class ThreadPool {
private BlockingQueue taskQueue = null;
private List<PoolThread> threads = new ArrayList<PoolThread>();
private boolean isStopped = false;
public ThreadPool(int noOfThreads, int maxNoOfTasks){
taskQueue = new BlockingQueue(maxNoOfTasks);
for(int i=0; i<noOfThreads; i++){
threads.add(new PoolThread(taskQueue));
}
for(PoolThread thread : threads){
thread.start();
}
}
public void synchronized execute(Runnable task){
if(this.isStopped) throw
new IllegalStateException("ThreadPool is stopped");
this.taskQueue.enqueue(task);
}
public synchronized void stop(){
this.isStopped = true;
for(PoolThread thread : threads){
thread.stop();
}
}
}
public class PoolThread extends Thread {
private BlockingQueue taskQueue = null;
private boolean isStopped = false;
public PoolThread(BlockingQueue queue){
taskQueue = queue;
}
public void run(){
while(!isStopped()){
try{
Runnable runnable = (Runnable) taskQueue.dequeue();
runnable.run();
} catch(Exception e){
//log or otherwise report exception,
//but keep pool thread alive.
}
}
}
public synchronized void stop(){
isStopped = true;
this.interrupt(); //break pool thread out of dequeue() call.
}
public synchronized void isStopped(){
return isStopped;
}
}
The thread pool implementation consists of two parts. A ThreadPool class which is the
public interface to the thread pool, and a PoolThread class which implements the threads
that execute the tasks.
To execute a task the method ThreadPool.execute(Runnable r) is called with a
Runnable implementation as parameter. The Runnable is enqueued in the
blocking queue internally, waiting to be dequeued.
The Runnable will be dequeued by an idle PoolThread and executed. You
can see this in the PoolThread.run() method. After execution the PoolThread
loops and tries to dequeue a task again, until stopped.
To stop the ThreadPool the method ThreadPool.stop() is called.
The stop called is noted internally in the isStopped member. Then each thread
in the pool is stopped by calling PoolThread.stop(). Notice how the
execute() method will throw an IllegalStateException if
execute() is called after stop() has been called.
The threads will stop
after finishing any task they are currently executing. Notice the
this.interrupt() call in PoolThread.stop(). This makes sure that
a thread blocked in a wait() call inside the taskQueue.dequeue()
call breaks out of the wait() call, and leaves the dequeue() method
call with an InterruptedException thrown. This exception is caught in the
PoolThread.run() method, reported, and then the isStopped variable
is checked. Since isStopped is now true, the PoolThread.run() will
exit and the thread dies.
Computers have been my hobby since I was 12. Now I'm a freelance Java developer. Like many other developers I am working on various private projects. Some are open source components (Butterfly Components - DI container, web ui, persistence api, mock test api etc.). Some are the tutorials at tutorials.jenkov.com. Yet others are web projects. I hold a bachelor degree in computer science and a master degree in IT focused on P2P networks. Jakob is a DZone MVB and is not an employee of DZone and has posted 22 posts at DZone. You can read more from them at their website.
- Login or register to post comments
- 10946 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Jakob Jenkov replied on Thu, 2008/06/26 - 3:26am