Files.list 在同一线程上并行运行

Files.list parallel runs on the same thread

我有以下代码循环访问目录中的文件。该目录包含 3 个文件。

预期输出

我希望输出包含不同线程的名称,因为我在流上使用了 parallel。但是它只为目录中的每个文件显示一个线程名称。

代码

package Concurrency;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Consumer;

public class SandBox 
{
    public static void main(String[] args)
    {
        try {
            Files.list(Path.of("/Users/x/Desktop/targets")).parallel().forEach(new Consumer<Path>() {
                @Override
                public void accept(Path path) {
                    System.out.println("From thread " + Thread.currentThread().getName());
                }
            });
        } catch(IOException e) {
            System.out.println(e.getMessage());
        }
    }
}

输出

From thread main
From thread main
From thread main

您查看的目录不够大。更改您的程序以计算线程数:

public static void main(String[] args) throws IOException {
    Path dir = Path.of(args[0]);

    var threads = new ConcurrentHashMap<String,AtomicInteger>();

    try(var stream = Files.list(dir)) {
        stream
        .parallel()
        //.peek(p -> System.out.println("Thread" + Thread.currentThread().getName()+" - "+p))
        .forEach(p -> threads.computeIfAbsent(Thread.currentThread().getName(), tn -> new AtomicInteger()).incrementAndGet());
    }

    System.out.println("Number of files: " + threads.values().stream().mapToInt(AtomicInteger::get).sum());
    System.out.println("Threads used: " + threads.size() +" => "+threads);
}

运行 在一个小目录上:

Number of files: 27
Threads used: 1 => {main=27}

来自大目录的示例:

Number of files: 4025
Threads used: 2 => {ForkJoinPool.commonPool-worker-1=1977, main=2048}