Eric Bruno

Dr. Dobb's Bloggers

Java Concurrency: The Executor Service

May 10, 2012

Exploring the Java Executor Service, which is useful for managing pools of threads, as well as the scheduling of future events

In Part 1 and Part 2 of this Java Concurrency series, we explored different ways to process requests in parallel via queues. In this installment, we'll explore the Java Executor Service, which is useful for managing pools of threads, as well as the scheduling of future events. First, let's look at a simple example.

The Java Executors

The Executorsclass helps you manage the creation of threads in a pool, their scheduling (if applicable), as well as their termination. In general, it helps you avoid having to create and manage threads yourself. For example, let's examine the following sample network application, where first a ServerSocket is created to listen for new client connections, and then those connections are managed:

We have the main class, JavaServer_Executor, which contains two nested classes, ListenerService and ClientHandler, which handle new client connections and manage those connections, respectively. We'll look at the nested classes in detail later. First, let's look at how the Executor service is used.

The first step is to create a thread pool via the method newFixedThreadPool(), where the number of threads is supplied and created up front. Alternatively, you can use:

newCachedThreadPool, which creates threads as needed, reusing them when it can.

The ListenerService class first creates a ServerSocket on a given port, where it will wait and listen for new client connection requests on that port. Since this class is a Runnable, the processing takes place in the run() method. To start this process, the ListenerService Runnable instance is itself submitted to the Executor thread pool as a task, where it's run in its own thread; no need for you to worry about creating the thread yourself.

Handling Incoming Clients

The ListenerService obediently waits for client connections in its own thread, and when a client does connect, it hands it off to the ClientHandler class to process, providing the resulting object to the Executor pool to manage the threading. The ClientHandler class (see below) is also a Runnable, and each instance runs in its own thread provided by the pool.

None of this code is specific to the Executor service, but it's included here to provide a complete working sample application.

Controlling Tasks

If you replace the call to pool.execute() in the ListenerService with pool.submit(), the resulting Future object that is returned can be used to process the related asynchronous event. For example, you can periodically call the isDone() method, which will return true when the Runnable terminates, to check for the completion of an asynchronous network event. Or, if the task is taking too long to complete, you can terminate it via the cancel() method. This saves you from writing all of the boilerplate code required to handle this thread synchronization yourself.

In the next installment, we'll take a look at Java.NIO Channels, and how NetworkChannel helps you improve the efficiency of this server application example. This blog is by no means a complete discussion on Java Executors. As such, we'll continue to explore it going forward, specifically at how periodic scheduling, via theScheduledExecutorService, can be useful.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!