Site Search:

Chapter 6 Task Execution

Back>

6.1 Executing tasks in threads


Most concurrent applications are organized around the execution of tasks: abstract, discrete units of work. The primary abstraction for task execution in the Java class libraries is Executor.

public interface Executor {
       void execute(Runnable command);
}

public interface Runnable {
       void run();
}

6.1.1 Executing tasks in threads

Independence facilitates concurrency, as independent tasks can be executed in parallel if there are adequate processing resources.

6.2 The Executor framework

Whenever you see code of the form:
         new Thread(runnable).start()
and you think you might at some point want a more flexible execution policy, seriously consider replacing it with he use of an Executor.

java.util.concurrent provides a flexible thread pool implementation as part of the Executor framework. Executor is based on the producer-consumer pattern, where activities that submit tasks are the producers and the threads that execute tasks are the consumers.

Example

6.2.4 Executor lifecycle

To address the issue of execution service lifecycle, the ExecutorService interface extends Executor, adding a number of methods for lifecycle management.

ExecutorService Example

Confusing Timer behavior

6.3 Finding exploitable parallelism

The real performance payoff of dividing program's workload into tasks comes when there area large number of independent, homogeneous tasks that can be processed concurrently.

Example: sequential page renderer

6.3.2 Result-bearing tasks: Callable and Future

ExecutorService's submit method takes either Callable or Runnable, returns a Future that can be used to retrieve the results or cancel the task.

Runnable and Callable describe abstract computational tasks. While Runnable returns no result, Callable returns result. Both Runnable and Callable are functional interfaces.

public interface Runnable {
       run();
}

public interface Callable<V> {
       V call() throws Exception;
}

Future represents the lifecycle of a task.

public interface Future<V> {
       boolean cancel(boolean mayInterruptIfRunning);
       boolean isCancelled();
       boolean isDone();
       V get() throws InterruptedException, ExecutionException, CancellationException;
       V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, CancellationException, TimeoutException;
}

Example: page renderer with Future

6.3.5 CompletionService: Executor meets BlockingQueue


A service that decouples the production of new asynchronous tasks from the consumption of the results of completed tasks. Producers submit tasks for execution. Consumers take completed tasks and process their results in the order they complete.
public interface CompletionService<V> {
       Future<V> poll();
       Future<V> take();
       Future<V> poll(long timeOut, TimeUnit unit);
       Future<V> submit(Callable<V> task);
       Future<V> submit(Runnable task, V result);
}

Example: page renderer with CompletionService


6.3.7 Placing time limits on tasks


Example: Fetching an advertisement with a time budget

Example: a travel reservation portal