![]() | |
|
In large-scale applications, it makes sense to separate thread management and creation from the rest of the application. Objects that encapsulate these functions are known as executors.
The java.util.concurrent
package defines three executor interfaces:
Executor
- a simple interface that supports launching new tasks:
public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, or in the calling * thread. */ void execute(Runnable command); }
The Executor
interface provides a single method, execute(..)
, designed to be a drop-in replacement for a common
thread-creation idiom. If r
is a Runnable
object, and e
is an Executor
object you
can replace:
(new Thread(r)).start();
with
e.execute(r);
However, the definition of execute(...)
is less specific. The low-level idiom creates a new thread and launches
it immediately. Depending on the Executor
implementation, execute
may do the same thing, but is more
likely to use an existing worker thread to run r
, or to place r
in a queue to wait for a worker thread
to become available.
The executor implementations in java.util.concurrent
are designed to make full use of the more advanced
ExecutorService
and ScheduledExecutorService
interfaces, although they also work with the base
Executor
interface.
ExecutorService
- a subinterface of Executor
, which adds features that help manage the lifecycle,
both of the individual tasks and of the executor itself:
public interface ExecutorService extends Executor { void shutdown(); List<Runnable> shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException; <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task); <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
The ExecutorService
interface supplements execute(...)
with a similar, but more versatile
submit(...)
method. Like execute(...)
, submit(...)
accepts Runnable
objects,
but also accepts Callable
objects, which allow the task to return a value:
public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. */ V call() throws Exception; }
The submit(...)
method returns a Future
object, which is used to retrieve the Callable
return value and to manage the status of both Callable
and
Runnable
tasks.
ExecutorService
also provides methods for submitting large collections of Callable
objects. Finally,
ExecutorService
provides a number of methods for managing the shutdown of the executor. To support immediate shutdown,
tasks should handle interrupts correctly.
ScheduledExecutorService
- a subinterface of ExecutorService
, supports future and/or periodic
execution of tasks:
public interface ScheduledExecutorService extends ExecutorService { public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }
The ScheduledExecutorService
interface supplements the methods of its parent ExecutorService
with schedule,
which executes a Runnable
or Callable
task after a specified delay. In addition, the interface defines
scheduleAtFixedRate
and scheduleWithFixedDelay
, which executes specified tasks repeatedly, at defined
intervals.
![]() ![]() ![]() |