Java Reference
In-Depth Information
calculation time for the sequential LongStream and just 22% of the time required to per-
form the five operations separately.
23.14 (Advanced) Interfaces Callable and Future
Interface Runnable provides only the most basic functionality for multithreaded program-
ming. In fact, this interface has limitations. Suppose a Runnable is performing a long cal-
culation and the application wants to retrieve the result of that calculation. The run
method cannot return a value, so shared mutable data would be required to pass the value
back to the calling thread. As you now know, this would require thread synchronization.
The Callable interface (of package java.util.concurrent ) fixes this limitation. The in-
terface declares a single method named call which returns a value representing the result
of the Callable 's task—such as the result of a long running calculation.
An application that creates a Callable likely wants to run it concurrently with other
Runnable s and Callable s. ExecutorService method submit executes its Callable argu-
ment and returns an object of type Future (of package java.util.concurrent ), which
represents the Callable 's future result. The Future interface get method blocks the calling
thread, and waits for the Callable to complete and return its result. The interface also
provides methods that enable you to cancel a Callable 's execution, determine whether the
Callable was cancelled and determine whether the Callable completed its task.
Executing Aysnchronous Tasks with CompletableFuture
Java SE 8 introduces class CompletableFuture (package java.util.concurrent ), which
implements the Future interface and enables you to asynchronously execute Runnable s that
perform tasks or Supplier s that return values. Interface Supplier , like interface Callable ,
is a functional interface with a single method (in this case, get ) that receives no arguments
and returns a result. Class CompletableFuture provides many additional capabilities that for
advanced programmers, such as creating CompletableFuture s without executing them im-
mediately, composing one or more CompletableFuture s so that you can wait for any or all
of them to complete, executing code after a CompletableFuture completes and more.
Figure 23.30 performs two long-running calculations sequentially, then performs
them again asynchronously using CompletableFuture s to demonstrate the performance
improvement from asynchronous execution on a multi-core system. For demonstration
purposes, our long-running calculation is performed by a recursive fibonacci method
(lines 73-79; similar to the one presented in Section 18.5). For larger Fibonacci values,
the recursive implementation can require significant computation time—in practice, it's
much faster to calculate Fibonacci values using a loop.
1
// FibonacciDemo.java
2
// Fibonacci calculations performed synchronously and asynchronously
3
import java.time.Duration;
4
import java.text.NumberFormat;
5
import java.time.Instant;
6
7
8
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
Fig. 23.30 | Fibonacci calculations performed synchronously and asynchronously. (Part 1 of 4.)
 
 
Search WWH ::




Custom Search