我正在使用ForkJoinPool创建一个私有线程池来处理大型单个数据流。我不是试图使用并行性来更快地处理流,而是在数据记录从流中读取后,让多个线程对数据记录执行相对较慢的操作。
以下是开发Spliterator的测试程序,该Spliterator将拆分并发值而不是实际工作负载,并假设单个数据流具有线程安全的getLine()方法:
try (ConcurrentReader reader = new ConcurrentReader("alphabet.txt")) {
int nThreads = 7;
FileSpliterator spliterator = new FileSpliterator(reader, nThreads);
Stream<String> fileStream = StreamSupport.stream(spliterator, true);
ForkJoinPool pool = new ForkJoinPool(nThreads);
pool.submit(() -> {
// print and sleep for 100 milliseconds
fileStream.parallel().forEach(s -> print(s));
}).get();
pool.shutdown();
}
catch (Exception e) {
e.printStackTrace();
}
这非常适合作为一个独立的Java程序,产生由线程处理的值的摘要,如下所示:
Thread Summary:
ForkJoinPool-1-worker-1 : 4
ForkJoinPool-1-worker-2 : 3
ForkJoinPool-1-worker-3 : 4
ForkJoinPool-1-worker-4 : 4
ForkJoinPool-1-worker-5 : 3
ForkJoinPool-1-worker-6 : 4
ForkJoinPool-1-worker-7 : 4
但是,如果我在JUnit测试中运行相同的代码,我会得到这样的摘要:
Thread Summary:
ForkJoinPool-1-worker-6 : 7
ForkJoinPool.commonPool-worker-1 : 6
ForkJoinPool.commonPool-worker-2 : 6
ForkJoinPool.commonPool-worker-3 : 7
所以我的问题是为什么它在测试套件中运行时部分使用公共池,最多4个线程?看起来流对ForkJoinPool的亲和力在某种程度上被破坏了。 JUnit测试或独立程序都没有设置任何JVM参数。