epubjs
Version:
Render ePub documents in the browser, across many devices
381 lines (369 loc) • 127 kB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Concurrency Utilities</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Concurrency Utilities"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-9-SECT-7"/>Concurrency Utilities</h1></div></div></div><p>So far in this chapter, we’ve demonstrated how to create and
synchronize threads at a low level, using Java language primitives. The
<a id="I_indexterm9_id719174" class="indexterm"/><code class="literal">java.util.concurrent</code>
package and subpackages introduced with Java 5.0 build on this
functionality, adding important threading utilities and codifying some
common design patterns by supplying standard implementations. Roughly in
order of generality, these areas include:</p><div class="variablelist"><dl><dt><span class="term"><span class="emphasis"><em>Thread-aware Collections
implementations</em></span></span></dt><dd><p>The <code class="literal">java.util.concurrent</code>
package augments the Java Collections API with several
implementations for specific threading models. These include timed
wait and blocking implementations of the <a id="I_indexterm9_id719204" class="indexterm"/><code class="literal">Queue</code> interface, as
well as nonblocking, concurrent-access optimized implementations of
the <code class="literal">Queue</code> and <a id="I_indexterm9_id719220" class="indexterm"/><code class="literal">Map</code> interfaces. The
package also adds “copy on write” <code class="literal">List</code> and <code class="literal">Set</code> implementations for extremely
efficient “almost always read” cases. These may sound complex, but
actually cover some fairly simple cases very well. We’ll cover the
Collections API in <a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a>.</p></dd><dt><span class="term"><span class="emphasis"><em>Executors</em></span></span></dt><dd><p><a id="I_indexterm9_id719257" class="indexterm"/> <code class="literal">Executor</code>s run
tasks, including <code class="literal">Runnable</code>s, and
abstract the concept of thread creation and pooling from the user.
Executors are intended to be a high-level replacement for the idiom
of creating new threads to service a series of jobs. Along with
<code class="literal">Executor</code>s, the <code class="literal">Callable</code> and <a id="I_indexterm9_id719287" class="indexterm"/><code class="literal">Future</code> interfaces
are introduced, which expand upon <code class="literal">Runnable</code> to allow management, value
return, and exception handling.</p></dd><dt><span class="term"><span class="emphasis"><em>Low-level synchronization constructs</em></span></span></dt><dd><p>The <a id="I_indexterm9_id719312" class="indexterm"/><code class="literal">java.util.concurrent.locks</code> package holds a
set of classes, including <a id="I_indexterm9_id719324" class="indexterm"/><code class="literal">Lock</code> and <a id="I_indexterm9_id719334" class="indexterm"/><code class="literal">Condition</code>, that
parallels the Java language-level synchronization primitives and
promotes them to the level of a concrete API. The locks package also
adds the concept of nonexclusive reader/writer locks, allowing for
greater concurrency in synchronized data access.</p></dd><dt><span class="term"><span class="emphasis"><em>High-level synchronization
constructs</em></span></span></dt><dd><p>This includes the classes <a id="I_indexterm9_id719355" class="indexterm"/><code class="literal">CyclicBarrier</code>,
<a id="I_indexterm9_id719366" class="indexterm"/><code class="literal">CountDownLatch</code>,
<a id="I_indexterm9_id719377" class="indexterm"/><code class="literal">Semaphore</code>, and
<a id="I_indexterm9_id719387" class="indexterm"/><code class="literal">Exchanger</code>. These
classes implement common synchronization patterns drawn from other
languages and systems and can serve as the basis for new high-level
tools.</p></dd><dt><span class="term"><span class="emphasis"><em>Atomic operations (sounds very James Bond, doesn’t
it?)</em></span></span></dt><dd><p>The <a id="I_indexterm9_id719408" class="indexterm"/><code class="literal">java.util.concurrent.atomic</code> package
provides wrappers and utilities for atomic, “all-or-nothing”
operations on primitive types and references. This includes simple
combination atomic operations like testing a value before setting it
and getting and incrementing a number in one operation.</p></dd></dl></div><p>With the possible exception of optimizations done by the Java VM for
the <code class="literal">atomic</code> operations package, all of
these utilities are implemented in pure Java, on top of the standard Java
language synchronization constructs. This means that they are in a sense
only convenience utilities and don’t truly add new capabilities to the
language. Their main role is to offer standard patterns and idioms in Java
threading and make them safer and more efficient to use. A good example of
this is the <code class="literal">Executor</code> utility, which
allows a user to manage a set of tasks in a predefined threading model
without having to delve into creating threads at all. Higher-level APIs
like this both simplify coding and allow for greater optimization of the
common cases.</p><p>We’ll look at each of these areas in the remainder of this chapter,
with the exception of the Collections implementations. We’ll discuss those
when we cover the Java Collections APIs in <a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a>.</p><p>Before we dive in, we should give a shout-out to Doug Lea, the
author of <span class="emphasis"><em>Concurrent Programming in Java</em></span>
(Addison-Wesley), who led the group that added these packages to Java and
is largely responsible for creating them.</p><div class="sect2" title="Executors"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-9-SECT-7.1"/>Executors</h2></div></div></div><p><a id="idx10491" class="indexterm"/>In this chapter, we’ve created a lot of <code class="literal">Thread</code>s and hopefully shown how to use them
effectively. But in the grand scheme of things, threads are a fairly
low-level programming tool and, without care, can be error-prone. When
we recognize certain common patterns that developers reproduce over and
over again using threads, it’s natural to want to elevate a pattern to
the level of an API. One such related pair of patterns is the concept of
an <span class="emphasis"><em>executor</em></span> service that manages tasks and that of
a <span class="emphasis"><em>thread pool</em></span> that services tasks in an efficient
way.</p><p><a id="I_indexterm9_id719508" class="indexterm"/>Thread pools have been implemented and reimplemented by
vast numbers of developers in one way or another over the years and when
you add in features like scheduling different threading models, they can
get quite complex. To address these issues, the <a id="I_indexterm9_id719517" class="indexterm"/><code class="literal">java.util.concurrent</code>
package includes interfaces for many default implementations of the
executor pattern for common threading models. This includes
sophisticated scheduling as well as asynchronous collection of results
from the tasks, if they require it. In general, you can use an <code class="literal">Executor</code> as a replacement for creating one-off
threads anywhere you need to execute <code class="literal">Runnable</code> objects. The advantage is that
understanding and modifying the behavior of your code later is a lot
easier when you work at this level.</p><p>For the simple case of running a number of tasks and watching for
their completion, we can consider the base <code class="literal">Executor</code> interface, which executes <code class="literal">Runnable</code> objects for us. A convenient thing
about <code class="literal">Executor</code> is that its companion
utility class <code class="literal">Executors</code> is a factory
for creating different kinds of <code class="literal">Executor</code> implementations. We’ll talk about the
various types it can produce in a bit, but for now let’s use the method
called <a id="I_indexterm9_id719577" class="indexterm"/><code class="literal">newFixedThreadPool()</code>,
which, as its name suggests, returns an <code class="literal">Executor</code> that is implemented using a thread
pool of a fixed size:</p><a id="I_9_tt522"/><pre class="programlisting"> <code class="n">Executor</code> <code class="n">executor</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newFixedThreadPool</code><code class="o">(</code> <code class="mi">3</code> <code class="o">)</code> <code class="o">;</code> <code class="c1">// 3 threads</code>
<code class="err"> </code>
<code class="n">List</code><code class="o"><</code><code class="n">Runnable</code><code class="o">></code> <code class="n">runnables</code> <code class="o">=</code> <code class="o">...</code> <code class="o">;</code>
<code class="k">for</code><code class="o">(</code> <code class="n">Runnable</code> <code class="n">task</code> <code class="o">:</code> <code class="n">runnables</code> <code class="o">)</code>
<code class="n">executor</code><code class="o">.</code><code class="na">execute</code><code class="o">(</code> <code class="n">task</code> <code class="o">);</code></pre><p>Here, we are submitting a number of <code class="literal">Runnable</code> tasks to our <code class="literal">Executor</code>, which executes them using a pool
with a maximum of three threads. If our list contains more than three
tasks, then some of them will have to wait until a thread is free to
service it. So, what happens when we submit the fourth item? The
<code class="literal">Executor</code> interface doesn’t really
specify that. It’s up to the particular implementation to decide.
Without specifying more about its type, we don’t know if an <code class="literal">Executor</code> is going to queue tasks, or if it
will use a pool to service them. Some <code class="literal">Executor</code> implementations may block or even
execute the <code class="literal">Runnable</code> right on the
<a id="I_indexterm9_id719648" class="indexterm"/><code class="literal">execute()</code> call in the
caller’s thread. But in this case (and for all <code class="literal">Executor</code>
implementations created for us by the <code class="literal">Executors</code> factory methods), tasks are
effectively put onto an unbounded queue. In the example, our loop
submits all of the tasks immediately and they are queued by the executor
until the three threads have serviced them.</p><p>With just a line or two of code in our example, we’ve been able to
throttle the concurrency of our task list and avoid the details of
constructing any threads ourselves. Later, if we decide we’d rather
execute the tasks one at a time, the change is trivial (allocate just
one thread!). Next, we’ll take a step up and look at manageable tasks
that produce values and executors that can schedule tasks for us.</p><div class="sect3" title="Tasks with results: Callable and Future"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.1"/>Tasks with results: Callable and Future</h3></div></div></div><p><a id="idx10444" class="indexterm"/> <a id="idx10446" class="indexterm"/> <a id="idx10463" class="indexterm"/>Because the <code class="literal">Runnable</code>
interface was created for <code class="literal">Thread</code>s
to consume, its API doesn’t allow for direct feedback to the caller.
The new <code class="literal">Callable</code> interface, which
is effectively a replacement for <code class="literal">Runnable</code>, rectifies this situation by
providing a <code class="literal">call()</code> method that both
returns a result and can throw exceptions. <code class="literal">Callable</code> is a generic class that is
parameterized by the type it returns. The following examples create a
<code class="literal">Callable</code> that returns an
integer:</p><a id="I_9_tt523"/><pre class="programlisting"> <code class="kd">class</code> <code class="nc">MyCallable</code> <code class="kd">implements</code> <code class="n">Callable</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="o">{</code>
<code class="kd">public</code> <code class="n">Integer</code> <code class="nf">call</code><code class="o">()</code> <code class="o">{</code> <code class="k">return</code> <code class="mi">2</code><code class="o">+</code><code class="mi">2</code><code class="o">;</code> <code class="o">}</code>
<code class="o">}</code>
<code class="c1">// or anonymously</code>
<code class="n">Callable</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">callable</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Callable</code><code class="o"><</code><code class="n">Integer</code><code class="o">>()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="n">Integer</code> <code class="nf">call</code><code class="o">()</code> <code class="o">{</code> <code class="k">return</code> <code class="mi">2</code><code class="o">+</code><code class="mi">2</code><code class="o">;</code> <code class="o">}</code>
<code class="o">};</code></pre><p>There is also a convenience method for bridging <code class="literal">Runnable</code>s to <code class="literal">Callable</code>s in the <code class="literal">Executors</code> class. It takes a <code class="literal">Runnable</code> and a fixed value to return as a
value when it completes:</p><a id="I_9_tt524"/><pre class="programlisting"> <code class="n">Callable</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">callable</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">callable</code><code class="o">(</code> <code class="n">runnable</code><code class="o">,</code>
<code class="mi">42</code> <code class="cm">/*return value*/</code> <code class="o">);</code></pre><p>The new <code class="literal">Future</code> class is used
with <code class="literal">Callable</code> and serves as a
handle to wait for and retrieve the result of the task or cancel the
task before it is executed. A <code class="literal">Future</code> is returned by the <code class="literal">submit()</code> methods of an <code class="literal">ExecutorService</code>, which is essentially a
beefed-up <code class="literal">Executor</code>. We’ll discuss
<code class="literal">ExecutorService</code>s in the next
section.</p><a id="I_9_tt525"/><pre class="programlisting"> <code class="n">Future</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">result</code> <code class="o">=</code> <code class="n">executorService</code><code class="o">.</code><code class="na">submit</code><code class="o">(</code> <code class="n">callable</code> <code class="o">);</code>
<code class="kt">int</code> <code class="n">val</code> <code class="o">=</code> <code class="n">result</code><code class="o">.</code><code class="na">get</code><code class="o">();</code> <code class="c1">// blocks until ready</code></pre><p><code class="literal">Future</code> is also a generic
interface, which is parameterized by its return type. This explains
the somewhat cute name. For example, a <code class="literal">Future<Integer></code> could be read as “a
future integer.” Future has both blocking and timed-wait <code class="literal">get()</code> methods to retrieve the result when it
is ready, as well as an <a id="I_indexterm9_id719891" class="indexterm"/><code class="literal">isDone()</code> test method
and a <a id="I_indexterm9_id719901" class="indexterm"/><code class="literal">cancel()</code> method to
stop the task if it hasn’t started yet. If the task has been
cancelled, you get a <a id="I_indexterm9_id719914" class="indexterm"/><code class="literal">CancellationException</code>
if you attempt to retrieve the result.</p><p>Enough said about these interfaces. Next, we’ll look at the
<code class="literal">ExecutorService</code>, which uses
them.<a id="I_indexterm9_id719934" class="indexterm"/><a id="I_indexterm9_id719941" class="indexterm"/><a id="I_indexterm9_id719948" class="indexterm"/></p></div><div class="sect3" title="ExecutorService"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.2"/>ExecutorService</h3></div></div></div><p><a id="idx10448" class="indexterm"/> <a id="idx10465" class="indexterm"/> <a id="idx10469" class="indexterm"/>Our first <code class="literal">Executor</code>
was little more than a sinkhole for <code class="literal">Runnable</code>s and, as we described, required
knowledge of the implementation to know how it would handle tasks. By
contrast, an <code class="literal">ExecutorService</code> is
intended to be an asynchronous task handler. Instead of an <code class="literal">execute()</code> method, it has <code class="literal">submit()</code> methods that accept a <code class="literal">Callable</code> (or <code class="literal">Runnable</code>) and return immediately with a
<code class="literal">Future</code> object that can be used to
manage the task and collect the result later. In addition to that, an
<code class="literal">ExecutorService</code> has a lifecycle
defined by its <a id="I_indexterm9_id720052" class="indexterm"/><code class="literal">shutdown()</code> method and
related methods that can be used to stop the service gracefully after
tasks are completed.</p><p><code class="literal">ExecutorService</code> extends
<code class="literal">Executor</code>. In fact, all of the
implementations returned by the <code class="literal">Executors</code> factory methods are actually
<code class="literal">ExecutorService</code>s—including the one
we used in our first example. We’ll look at these factory methods to
see what kind of services are offered.</p><p><code class="literal">Executors</code> offers three types
of <code class="literal">ExecutorService</code>
implementations:</p><div class="variablelist"><dl><dt><span class="term"><code class="literal">newFixedThreadPool(int)</code></span></dt><dd><p><a id="I_indexterm9_id720111" class="indexterm"/>This is the classic thread pool with a specified
maximum pool size and an unbounded queue for task submission. If
a thread dies for some reason while handling a task, a new one
will be created to replace it. Threads are never removed from
the pool until the service is shut down.</p></dd><dt><span class="term"><code class="literal">newCachedThreadPool()</code></span></dt><dd><p><a id="I_indexterm9_id720129" class="indexterm"/>This pool uses an open-ended number of threads
that grows and shrinks with demand. The main advantage of this
service is that threads are cached for a period of time and
reused, eliminating the overhead of creating new threads for
short-lived tasks. Threads that are not used for one minute are
removed. Tasks are submitted directly to threads; there is no
real queuing.</p></dd><dt><span class="term"><code class="literal">newSingleThreadExecutor()</code></span></dt><dd><p><a id="I_indexterm9_id720149" class="indexterm"/>This <code class="literal">ExecutorService</code> uses a single thread
to execute tasks from an unbounded queue. In this sense, it is
identical to a fixed thread pool with a pool size of <code class="literal">1</code>.</p></dd></dl></div><p>Let’s look at a more realistic usage of an <code class="literal">ExecutorService</code>, drawn from the <code class="literal">Tiny</code><code class="literal">Httpd</code> example in <a class="xref" href="ch13.html" title="Chapter 13. Network Programming">Chapter 13</a>. In that chapter, we create a mini-web
server to illustrate features of the networking APIs. Here, we won’t
show the networking details, but we’ll implement the main request
dispatching loop for the example using a thread pool executor service.
(Flip to <a class="xref" href="ch13.html" title="Chapter 13. Network Programming">Chapter 13</a> to see the
implementation of the <code class="literal">Runnable</code>
client-connection handler class. That class works equally well with
both examples.) Here we
go:</p><a id="I_9_tt526"/><pre class="programlisting"> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">ExecutorHttpd</code>
<code class="o">{</code>
<code class="n">ExecutorService</code> <code class="n">executor</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newFixedThreadPool</code><code class="o">(</code><code class="mi">3</code><code class="o">);</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">start</code><code class="o">(</code> <code class="kt">int</code> <code class="n">port</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">IOException</code>
<code class="o">{</code>
<code class="kd">final</code> <code class="n">ServerSocket</code> <code class="n">ss</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ServerSocket</code><code class="o">(</code> <code class="n">port</code> <code class="o">);</code>
<code class="k">while</code> <code class="o">(</code> <code class="o">!</code><code class="n">executor</code><code class="o">.</code><code class="na">isShutdown</code><code class="o">()</code> <code class="o">)</code>
<code class="n">executor</code><code class="o">.</code><code class="na">submit</code><code class="o">(</code> <code class="k">new</code> <code class="n">TinyHttpdConnection</code><code class="o">(</code> <code class="n">ss</code><code class="o">.</code><code class="na">accept</code><code class="o">()</code> <code class="o">)</code> <code class="o">);</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">shutdown</code><code class="o">()</code> <code class="kd">throws</code> <code class="n">InterruptedException</code> <code class="o">{</code>
<code class="n">executor</code><code class="o">.</code><code class="na">shutdown</code><code class="o">();</code>
<code class="n">executor</code><code class="o">.</code><code class="na">awaitTermination</code><code class="o">(</code> <code class="mi">30</code><code class="o">,</code> <code class="n">TimeUnit</code><code class="o">.</code><code class="na">SECONDS</code> <code class="o">);</code>
<code class="n">executor</code><code class="o">.</code><code class="na">shutdownNow</code><code class="o">();</code>
<code class="o">}</code>
<code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code> <code class="n">argv</code><code class="o">[]</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">Exception</code>
<code class="o">{</code>
<code class="k">new</code> <code class="nf">ExecutorHttpd</code><code class="o">().</code><code class="na">start</code><code class="o">(</code> <code class="n">Integer</code><code class="o">.</code><code class="na">parseInt</code><code class="o">(</code><code class="n">argv</code><code class="o">[</code><code class="mi">0</code><code class="o">])</code> <code class="o">);</code>
<code class="o">}</code>
<code class="o">}</code></pre><p>The <code class="literal">ExecutorHttpd</code> class holds
an instance of a fixed thread pool <code class="literal">ExecutorService</code> with three threads to
service client connections. In the <code class="literal">start()</code> method of our class, we create a
<code class="literal">ServerSocket</code> that accepts incoming
network connections. We then enter a loop that runs as long as our
service is not flagged to shut down. Inside the loop, we create a new
connection handler (a <code class="literal">Runnable</code>
instance of <code class="literal">TinyHttpdConnection</code>)
for each connection and submit it to the executor. The <code class="literal">shutdown()</code> method of our class illustrates a
graceful termination. First, we call <code class="literal">shutdown()</code> on the executor, which causes the
service to stop accepting new tasks and allow the currently running
ones to complete. Then we wait a reasonable period of time for all web
requests to finish (30 seconds), using the <code class="literal">awaitTermination()</code> method before trying a
less graceful ending with <code class="literal">shutdownNow()</code>. <code class="literal">shutdownNow()</code> attempts to interrupt or
otherwise stop threads as quickly as possible. We leave things there,
but the method actually returns a <code class="literal">List</code> of tasks that remain hung after the
attempt. Finally, we have a <code class="literal">main()</code>
method that exercises our example by creating an instance of <code class="literal">ExecutorHttpd</code> on a port specified as an
argument to the program.<a id="I_indexterm9_id720315" class="indexterm"/><a id="I_indexterm9_id720322" class="indexterm"/><a id="I_indexterm9_id720329" class="indexterm"/></p></div><div class="sect3" title="Collective tasks"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.3"/>Collective tasks</h3></div></div></div><p><a id="idx10445" class="indexterm"/> <a id="idx10447" class="indexterm"/> <a id="idx10464" class="indexterm"/>In addition to its individual task <code class="literal">submit()</code> methods, <code class="literal">ExecutorService</code> also offers a set of
collective <a id="I_indexterm9_id720393" class="indexterm"/><code class="literal">invokeAll()</code> and
<a id="I_indexterm9_id720403" class="indexterm"/><code class="literal">invokeAny()</code> executor
methods that submit multiple tasks as a group and return results
either when they are all complete or when the first one completes,
respectively. With this, we could reproduce our first example using a
<code class="literal">List</code> of <code class="literal">Callable</code>s like this:</p><a id="I_9_tt527"/><pre class="programlisting"> <code class="n">List</code><code class="o"><</code><code class="n">Callable</code><code class="o"><</code><code class="n">Integer</code><code class="o">>></code> <code class="n">taskList</code> <code class="o">=</code> <code class="o">...;</code>
<code class="n">ExecutorService</code> <code class="n">execService</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newFixedThreadPool</code><code class="o">(</code><code class="mi">3</code><code class="o">);</code>
<code class="n">List</code><code class="o"><</code><code class="n">Future</code><code class="o"><</code><code class="n">Integer</code><code class="o">>></code> <code class="n">resultList</code> <code class="o">=</code> <code class="n">execService</code><code class="o">.</code><code class="na">invokeAll</code><code class="o">(</code> <code class="n">taskList</code> <code class="o">);</code></pre><p>By contrast, the <code class="literal">invokeAny()</code>
method returns just the first successfully completed task’s result
(cancelling all the remaining unexecuted tasks):</p><a id="I_9_tt528"/><pre class="programlisting"> <code class="kt">int</code> <code class="n">result</code> <code class="o">=</code> <code class="n">execService</code><code class="o">.</code><code class="na">invokeAny</code><code class="o">(</code> <code class="n">taskList</code> <code class="o">);</code></pre><p>Both methods also offer timed wait versions that time out after
a specified period of time.<a id="I_indexterm9_id720459" class="indexterm"/><a id="I_indexterm9_id720466" class="indexterm"/><a id="I_indexterm9_id720473" class="indexterm"/></p></div><div class="sect3" title="Scheduled tasks"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.4"/>Scheduled tasks</h3></div></div></div><p><a id="idx10450" class="indexterm"/> <a id="idx10467" class="indexterm"/> <a id="idx10479" class="indexterm"/>For tasks that you’d like to run at a future time or on
a periodic basis, use the <a id="I_indexterm9_id720526" class="indexterm"/><code class="literal">ScheduledExecutorService</code>. <code class="literal">ScheduledExecutorService</code> is an <code class="literal">ExecutorService</code> with additional “schedule”
methods that take a delay for a <code class="literal">Runnable</code> or <code class="literal">Callable</code> or a period specification for a
<code class="literal">Runnable</code>. Two additional factory
methods of <code class="literal">Executors</code> produce
scheduled executors:</p><a id="I_9_tt529"/><pre class="programlisting"> <code class="n">Executors</code><code class="o">.</code><code class="na">newScheduledThreadPool</code><code class="o">(</code><code class="kt">int</code><code class="o">);</code>
<code class="n">Executors</code><code class="o">.</code><code class="na">newSingleThreadScheduledExecutor</code><code class="o">();</code></pre><p>These are exactly like the similarly named methods for regular
executor services, with the exception of returning a scheduled
executor type.</p><p>To execute a task in the future, you specify a delay from the
current time. For example:</p><a id="I_9_tt530"/><pre class="programlisting"> <code class="n">ScheduledExecutorService</code> <code class="n">exec</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newScheduledThreadPool</code><code class="o">(</code><code class="mi">3</code><code class="o">);</code>
<code class="n">exec</code><code class="o">.</code><code class="na">schedule</code><code class="o">(</code> <code class="n">runnable</code><code class="o">,</code> <code class="mi">60</code><code class="o">,</code> <code class="n">TimeUnit</code><code class="o">.</code><code class="na">SECONDS</code> <code class="o">);</code> <code class="c1">// run one minute in the </code>
<code class="c1">// future</code>
<code class="c1">// run at specified date and time</code>
<code class="n">Calendar</code> <code class="n">futureDate</code> <code class="o">=</code> <code class="o">...;</code> <code class="c1">// convertfrom calendar</code>
<code class="n">Date</code> <code class="n">date</code> <code class="o">=</code> <code class="n">futureDate</code><code class="o">.</code><code class="na">getTime</code><code class="o">();</code> <code class="c1">// to Date</code>
<code class="kt">long</code> <code class="n">delay</code> <code class="o">=</code> <code class="n">date</code><code class="o">.</code><code class="na">getTime</code><code class="o">()</code> <code class="o">-</code> <code class="n">System</code><code class="o">.</code><code class="na">currentTimeMillis</code><code class="o">();</code> <code class="c1">// to relative </code>
<code class="c1">// millis</code>
<code class="n">exec</code><code class="o">.</code><code class="na">schedule</code><code class="o">(</code> <code class="n">runnable</code><code class="o">,</code> <code class="n">delay</code><code class="o">,</code> <code class="n">TimeUnit</code><code class="o">.</code><code class="na">MILLISECONDS</code> <code class="o">);</code> <code class="c1">// run at specified </code>
<code class="c1">// date</code></pre><p><a id="I_indexterm9_id720602" class="indexterm"/>For periodic work, there are two kinds of recurring
schedules—fixed delay and fixed rate. <span class="emphasis"><em>Fixed delay</em></span>
means that a fixed amount of time elapses between the end of the
task’s execution and the beginning of the next execution.
<span class="emphasis"><em>Fixed rate</em></span> means that the task should begin
execution at fixed time intervals, regardless of how long the task
takes. The difference comes into play when the time to execute the
task is long relative to the interval. The following snippet schedules
a logfile cleanup to occur in 12 hours and every 12 hours
thereafter:</p><a id="I_9_tt531"/><pre class="programlisting"> <code class="n">Runnable</code> <code class="n">cleanup</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Runnable</code><code class="o">()</code> <code class="o">{</code>
<code class="kd">public</code> <code class="kt">void</code> <code class="nf">run</code><code class="o">()</code> <code class="o">{</code> <code class="n">cleanUpLogFiles</code><code class="o">();</code> <code class="o">}</code>
<code class="o">};</code>
<code class="kt">long</code> <code class="n">period</code> <code class="o">=</code> <code class="mi">12</code><code class="o">*</code><code class="mi">60</code><code class="o">*</code><code class="mi">60</code><code class="o">,</code> <code class="n">delay</code> <code class="o">=</code> <code class="n">period</code><code class="o">;</code> <code class="c1">// seconds</code>
<code class="n">Future</code><code class="o"><?></code> <code class="n">logService</code> <code class="o">=</code> <code class="n">executionService</code><code class="o">.</code><code class="na">scheduleAtFixedRate</code><code class="o">(</code>
<code class="n">cleanup</code><code class="o">,</code> <code class="n">delay</code><code class="o">,</code> <code class="n">period</code><code class="o">,</code> <code class="n">TimeUnit</code><code class="o">.</code><code class="na">SECONDS</code> <code class="o">);</code></pre><p>Because the task for periodic schedules is a <code class="literal">Runnable</code>, the <code class="literal">Future</code> object does not return a useful value
(it returns <code class="literal">null</code>) so we don’t
specify a parameter type in its generic type instantiation. The
<code class="literal">Future</code> is still useful for
cancelling the task at a later time if we wish:</p><a id="I_9_tt532"/><pre class="programlisting"> <code class="n">logService</code><code class="o">.</code><code class="na">cancel</code><code class="o">();</code></pre><p>We should mention that the <a id="I_indexterm9_id720671" class="indexterm"/><code class="literal">ScheduledExecutorService</code> bears a great deal
of similarity to the <code class="literal">java.util.Timer</code> class that we’ll discuss in
<a class="xref" href="ch11.html" title="Chapter 11. Core Utilities">Chapter 11</a>, especially with regard to the
periodic schedules. A <code class="literal">java.util.Timer</code> is always single-threaded,
however.<a id="I_indexterm9_id720700" class="indexterm"/><a id="I_indexterm9_id720707" class="indexterm"/><a id="I_indexterm9_id720714" class="indexterm"/></p></div><div class="sect3" title="CompletionService"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.5"/>CompletionService</h3></div></div></div><p><a id="I_indexterm9_id720728" class="indexterm"/> <a id="I_indexterm9_id720739" class="indexterm"/>A <a id="I_indexterm9_id720748" class="indexterm"/><code class="literal">CompletionService</code> is
a lightweight queue-like frontend to an executor. The <code class="literal">CompletionService</code> provides <code class="literal">submit()</code> methods, which delegate their tasks
to a particular instance of <code class="literal">Executor</code>, and then provides <a id="I_indexterm9_id720776" class="indexterm"/><code class="literal">take()</code> and <a id="I_indexterm9_id720787" class="indexterm"/><code class="literal">poll()</code> methods for
retrieving <code class="literal">Future</code> results for
completed tasks. Think of a <code class="literal">CompletionService</code> as a babysitter for the
<code class="literal">Future</code>s, allowing you to easily
gather up only completed results (as opposed to having to check each
<code class="literal">Future</code> yourself to see which ones
have finished and in what order). <a id="I_indexterm9_id720821" class="indexterm"/><code class="literal">ExecutorCompletionService</code> is a concrete
implementation of <code class="literal">CompletionService</code>
that takes an <code class="literal">Executor</code> in its
constructor:</p><a id="I_9_tt533"/><pre class="programlisting"> <code class="n">Executor</code> <code class="n">executor</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newFixedThreadPool</code><code class="o">(</code><code class="mi">3</code><code class="o">);</code>
<code class="n">CompletionService</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">completionService</code> <code class="o">=</code>
<code class="k">new</code> <code class="n">ExecutorCompletionService</code><code class="o"><</code><code class="n">Integer</code><code class="o">>(</code> <code class="n">executor</code> <code class="o">);</code>
<code class="n">completionService</code><code class="o">.</code><code class="na">submit</code><code class="o">(</code> <code class="n">callable</code> <code class="o">);</code>
<code class="n">completionService</code><code class="o">.</code><code class="na">submit</code><code class="o">(</code> <code class="n">runnable</code><code class="o">,</code> <code class="n">resultValue</code> <code class="o">);</code>
<code class="c1">// poll for result</code>
<code class="n">Future</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">result</code> <code class="o">=</code> <code class="n">completionService</code><code class="o">.</code><code class="na">poll</code><code class="o">();</code>
<code class="k">if</code> <code class="o">(</code> <code class="n">result</code> <code class="o">!=</code> <code class="kc">null</code> <code class="o">)</code>
<code class="c1">// use value...</code>
<code class="c1">// block, waiting for result</code>
<code class="n">Future</code><code class="o"><</code><code class="n">Integer</code><code class="o">></code> <code class="n">result</code> <code class="o">=</code> <code class="n">completionService</code><code class="o">.</code><code class="na">take</code><code class="o">();</code></pre></div><div class="sect3" title="The ThreadPoolExecutor implementation"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.6"/>The ThreadPoolExecutor implementation</h3></div></div></div><p><a id="idx10451" class="indexterm"/> <a id="idx10468" class="indexterm"/> <a id="idx10489" class="indexterm"/>At various times in this chapter, we’ve referred to the
different executor services produced by the <code class="literal">Executors</code> factory as different
implementations of <code class="literal">ExecutorService</code>.
But these implementations are just different configurations of a
single, highly flexible implementation of <code class="literal">ExecutorService</code> called <a id="I_indexterm9_id720923" class="indexterm"/><code class="literal">ThreadPoolExecutorService</code>. You can use this
implementation directly if you want; it offers some additional
features. The primary constructor for <code class="literal">ThreadPoolExecutorService</code> allows you to
specify both a “core” thread pool size and a maximum size, as well as
a thread timeout value for removing idle threads. The core size is a
minimum number of threads which, once created, are allowed to live
indefinitely. The constructor also allows you to provide the task
queue (an implementation of <code class="literal">BlockingQueue</code>) on which new tasks are
placed. This last feature allows you to govern the queuing policy
yourself. You could specify a queue with a limited capacity:</p><a id="I_9_tt534"/><pre class="programlisting"> <code class="n">ExecutorService</code> <code class="n">executorService</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ThreadPoolExecutor</code><code class="o">(</code>
<code class="n">corePoolSize</code><code class="o">,</code> <code class="n">maximumPoolSize</code><code class="o">,</code> <code class="n">keepAliveTime</code><code class="o">,</code> <code class="n">timeUnit</code><code class="o">,</code> <code class="n">taskQueue</code> <code class="o">);</code></pre><p>The <code class="literal">ThreadPoolExecutor</code>
implementation also has methods that allow you to change the core and
maximum pool size while the service is active or to “prestart” the
core threads before the service is used.</p><p>Actually, these last features bring up an interesting issue. If
we know that our executor service is an implementation of <code class="literal">ThreadPoolExecutor</code>, we can cast it at
runtime to get access to these extra methods and do things like change
the pool size. This may not be what the designers of some services had
in mind; in fact, it could be downright dangerous in the wrong hands.
For this reason, <code class="literal">Executors</code> offers a
number of “unconfigurable” wrapper methods that act something like the
“unmodifiable” collection methods we’ll see in the Java Collections
API. These methods wrap an executor service in a delegator object that
does not expose the implementation to the caller:</p><a id="I_9_tt535"/><pre class="programlisting"> <code class="n">ExecutorService</code> <code class="n">tweakable</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">newFixedThreadPool</code><code class="o">();</code>
<code class="n">ExecutorService</code> <code class="n">safe</code> <code class="o">=</code> <code class="n">Executors</code><code class="o">.</code><code class="na">unconfigurableExecutorService</code><code class="o">(</code> <code class="n">tweakable</code> <code class="o">);</code></pre><p>An application server might, for example, wrap a service to
protect itself from individual applications modifying (intentionally
or accidentally) a global service used by many applications.<a id="I_indexterm9_id721009" class="indexterm"/><a id="I_indexterm9_id721016" class="indexterm"/><a id="I_indexterm9_id721024" class="indexterm"/></p></div><div class="sect3" title="Thread production"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-9-SECT-7.1.7"/>Thread production</h3></div></div></div><p><a id="I_indexterm9_id721038" class="indexterm"/> <a id="I_indexterm9_id721049" class="indexterm"/>We said that the <code class="literal">Executor</code> pattern is a general replacement
for using <code class="literal">Thread</code>s to run simple
tasks. Although <code class="literal">Executor</code>s shield us
from <code class="literal">Thread</code> creation, there still
may be cases where we want some control over how the threads used in
our various thread pool implementations are constructed or set up. For
this reason and to standardize <code class="literal">Thread</code> production in general, the
concurrency package adds an explicit, factory API for thread
creation.</p><p>The <a id="I_indexterm9_id721090" class="indexterm"/><code class="literal">ThreadFactory</code>
interface provides a <a id="I_indexterm9_id721101" class="indexterm"/><code class="literal">newThread()</code> method.
One of these factories is used by all service implementations that
create threads. All of the factory methods of <code class="literal">Executors</code> have an additional form that
accepts an explicit <code class="literal">ThreadFactory</code>
as an argument. You can get the default thread factory used by these
with the <a id="I_indexterm9_id721125" class="indexterm"/><code class="literal">Executors.defaultThreadFactory()</code> method. You
could supply your own <code class="literal">ThreadFactory</code>
to perform custom setup, such as <code class="literal">ThreadLocal</code> values or priorities.</p></div><div class="sect3" title="The Fork/Join framework"><div class="titlepage"><div><div><h3 class="title"><a id="id1281809"/>The Fork/Join framework</h3></div></div></div><p><a id="idx10449" class="indexterm"/> <a id="idx10466" class="indexterm"/> <a id="idx10470" class="indexterm"/>So far we’ve seen how the Java concurrency utilities can
be used to manage simple parallel programming scenarios. We’ve seen
that we can submit many tasks to an <code class="literal">ExecutorService</code> and collect result values if
needed through <code class="literal">Futures</code>. We’ve seen
that we can schedule tasks to run at specified times and with
specified frequencies. We’ve seen that we can delve into the details
of the pooling and control the degree of parallelism (how many threads
are used) if we wish. Later in this chapter, we’ll look at APIs that
help us coordinate threads so that we can do more complex jobs that
require cooperation or explicit phases of operation in their data
handling. In this section, we’ll look at an API that helps you
coordinate tasks in another way—by helping you take “scaleable” tasks
and divide them up to match the processing power available at any
given time.</p><p>Let’s imagine that you have a task that performs a complex
computation like rendering video or generating a complicated image. A
natural place to start in parallizing it would be to divide the work
for one frame or image into a fixed number of parts and feed them to
an executor service. The executor service would be tuned to have as
many threads as you wish to use (perhaps the same number as the number
of CPUs or “cores” on your machine) and would assign each part to its
own thread. If each task (each chunk of the image) requires about the
same amount of work to complete and nothing else is competing for time
on your computer, then this scenario is pretty optimal. We’d expect
that each part of the image would be finished at about the same time
and we’ll be able to stitch them all together effectively. But what if
some parts of the image are dramatically harder to render than other
parts? What if one chunk takes ten or a hundred or a thousand times as
much CPU power as another? (Imagine how much faster it may be to
render a empty part of an image, for example.) Then we may find
ourselves in a situation where many of the threads sit idle, while a
few threads churn away doing all of the hard work. What can we do to
address this?</p><p>Well, one approach would be to simply make our tasks more finely
grained. We could make our individual jobs so small that no single one
could possibly monopolize a thread for long. However, when tasks can
vary in degree of difficulty by many orders of magnitude, this could
lead to creating a very large number of tiny tasks and would probably
be very inefficient, with threads switching jobs and, even worse,
moving data around to accommodate the somewhat random order in which