Java Reference
In-Depth Information
Listing 6-5. Using Lambdas to Define Fork/Join Tasks
import java.util.concurrent.*;
import java.util.stream.*;
public class Listing5 {
public static void printPrimes(int maxBitLength) {
Stream.iterate(1, i -> i+1).limit(maxBitLength).parallel()
.map(i ->
ForkJoinTask.adapt(() -> PrimeFactory.ofLength(i)).fork()
)
.map(ForkJoinTask::join)
.forEach(System.out::println);
}
public static void main(String[] args) {
DemoRunner.run(Listing5::printPrimes);
}
}
This code executes in about 14 seconds on my machine. That means this code is just as performant as
the hand-rolled executor code before, and it is strikingly shorter. If all you are doing is CPU-intensive work,
or if it is primarily CPU-intensive work with some very brief blocking work (such as reading from a private
file on a local disk), then this is a perfect solution for you.
Stream Parallelism
In the last chapter, we discovered that there were sequential and parallel streams, and sequential streams
were the default. And in the last section, we used a parallel stream for maximum concurrency. But what
exactly is going on when we switch from sequential to parallel streams? To see the difference, we can run the
code in Listing 6-6.
Listing 6-6. Code to Demonstrate the Difference Between Sequential and Parallel Streams
// NumberStreamFactory.java
import java.util.stream.*;
public class NumberStreamFactory {
/**
* Returns a parallel stream which returns the {@code int} values from 1 to {@code value}.
*
* @param value The value to count up to; must be positive.
* @return A stream that returns 1, 2, ..., {@code value}.
*/
 
Search WWH ::




Custom Search