Java Reference
In-Depth Information
If you're experiencing déjà vu right now, that's probably because you have seen this
scheme before. This is
exactly
how events are handled in Swing, the AWT, and JavaBeans.
The AWT runs in a separate thread from the rest of the program. Components and
beans inform you of events by calling back to methods declared in particular interfaces,
such as
ActionListener
and
PropertyChangeListener
. Your listener objects register
their interests in events fired by particular components using methods in the
Compo
nent
class, such as
addActionListener()
and
addPropertyChangeListener()
. Inside
the component, the registered listeners are stored in a linked list built out of
java.awt.AWTEventMulticaster
objects. More generally this is known as the
Observ‐
er
design pattern.
Futures, Callables, and Executors
Java 5 introduced a new approach to multithreaded programming that makes it some‐
what easier to handle callbacks by hiding the details. Instead of directly creating a thread,
you create an
ExecutorService
that will create threads for you as needed. You submit
Callable
jobs to the
ExecutorService
and for each one you get back a
Future
. At a
later point, you can ask the
Future
for the result of the job. If the result is ready, you get
it immediately. If it's not ready, the polling thread blocks until it is ready. The advantage
is that you can spawn off many different threads, then get the answers you need in the
order you need them.
For example, suppose you need to find the maximum value in a large array of numbers.
Implemented naively, this takes O(n) time where n is the number of elements in the
array. However, you can go faster than that if you split the work into multiple threads,
each running on a separate core. For purposes of illustration, let's assume two threads
are desired.
The
Callable
interface defines a single
call()
method that can generically return any
type.
Example 3-9
is a
Callable
that finds the maximum value in a subsection of an
array in the most obvious way possible.
Example 3-9. FindMaxTask
import
java.util.concurrent.Callable
;
class
FindMaxTask
implements
Callable
<
Integer
>
{
private
int
[]
data
;
private
int
start
;
private
int
end
;
FindMaxTask
(
int
[]
data
,
int
start
,
int
end
)
{
this
.
data
=
data
;
this
.
start
=
start
;
this
.
end
=
end
;
}