DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Tomorrow’s Cloud Today: Unpacking the Future of Cloud Computing
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud

Trending

  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Tomorrow’s Cloud Today: Unpacking the Future of Cloud Computing
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud
  1. DZone
  2. Coding
  3. Java
  4. Java Concurrency Tutorial: Thread Pools

Java Concurrency Tutorial: Thread Pools

Jakob Jenkov user avatar by
Jakob Jenkov
·
Jun. 26, 08 · Tutorial
Like (3)
Save
Tweet
Share
102.63K Views

Join the DZone community and get the full member experience.

Join For Free

Thread Pools are useful when you need to limit the number of threads running in your application at the same time. There is a performance overhead associated with starting a new thread, and each thread is also allocated some memory for its stack etc.

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.

Java (programming language) Thread pool Task (computing)

Published at DZone with permission of Jakob Jenkov. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Tomorrow’s Cloud Today: Unpacking the Future of Cloud Computing
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: