1

我正在使用 ForkJoinPool 创建一个私有线程池,用于处理大型的单个数据流。我不是试图使用并行性来更快地处理流,而是让多个线程在从流中读取数据记录后对它们执行相对较慢的操作。

以下是开发 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 参数。

4

0 回答 0