ExerciseWarm-up
Warm-up
Find out whose threads you are using
10 minintermediate2–10 yrs
One concept, guided. Near-impossible to fail.
What this teaches
- parallelStream submits to one JVM-wide common ForkJoinPool
- The calling thread joins the work, so it is not asynchronous
- Parallelism is cores minus one, decided by the machine and not by you
- A parallel stream inside your own ForkJoinPool task uses that pool instead
Starter
Starter.java
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
/**
* Warm-up: whose threads are these?
*
* parallelStream() does not create threads. Finding out which threads it does
* use, by printing their names, answers most of this topic on its own.
*/
public class Starter {
public static void main(String[] args) throws Exception {
// TODO 1: predict the thread names before running. Then look at the
// prefix — it names the pool, and the pool is the whole point.
Set<String> threads = ConcurrentHashMap.newKeySet();
IntStream.range(0, 10_000).parallel()
.forEach(i -> threads.add(Thread.currentThread().getName()));
System.out.println("distinct threads : " + threads.size());
System.out.println("names : " + new TreeSet<>(threads));
// TODO 2: one of those names is not a worker. Which, and what does its
// presence tell you about whether parallelStream is asynchronous?
// TODO 3: print ForkJoinPool.getCommonPoolParallelism() and
// Runtime.getRuntime().availableProcessors(). State the relationship,
// then say what happens in a container limited to one core.
// TODO 4: run two parallel streams from two different threads at the
// same time and collect the names from both. Do they share workers?
// That answer is the reason this entry exists.
// TODO 5: now run the same stream inside your own pool:
//
// ForkJoinPool mine = new ForkJoinPool(2);
// Set<String> names = mine.submit(() -> ...).get();
//
// The names change. Note that you did not pass the pool to the stream
// — say where the stream found it, and why there is no overload that
// takes one.
// TODO 6: in one sentence, explain to a colleague why adding
// .parallelStream() to a slow remote call can make an unrelated
// endpoint time out.
}
}Run it locally:
cd exercises/java/java8/parallel-stream-pitfalls/01-warmup
javac Starter.java -d /tmp/out && java -cp /tmp/out StarterDone when
- You printed the thread names and identified the pool by name
- You showed the calling thread doing work
- You ran the same stream inside your own pool and saw the names change
- You can say why a slow task here affects unrelated code in the same JVM