【问题标题】:Files.list parallel runs on the same threadFiles.list 并行运行在同一个线程上
【发布时间】:2022-01-18 09:44:11
【问题描述】:

我有以下代码循环遍历目录中的文件。该目录包含 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

【问题讨论】:

  • 这取决于您的环境,但您通常需要更大的流来进行并行处理。
  • 读取目录列表取决于文件系统,文件系统通常没有并行处理,打印到System.out 有内部同步,因此并行处理没有任何好处,您只有三个文件。见证并行处理的期望从何而来?
  • @Holger 你是什么意思?我不希望文件系统被并行处理。你对java有任何经验吗?我希望消费者并行运行,因为我在 Stream 对象上调用了 parallel()。看看接受的答案。

标签: java java-stream


【解决方案1】:

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

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}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多