多线程文件读取

时间:2016-02-18 20:03:38

标签: java multithreading

我有一堆我想要阅读的文件,但每个文件都经过加密和压缩。我想通过使用每个核心打开文件,解密并解压缩来加快进程。然后传递给下一个未使用的文件。

现在我有一个for循环,一次读取一个文件解密,解压缩并传递给下一个文件。

怎么做?

2 个答案:

答案 0 :(得分:1)

我认为文件IO可能比处理更容易成为瓶颈。无论哪种方式,并行读取文件只会导致硬盘抖动 - 可能是SSD或高端RAID会应付。

我会这样构建程序:

  • main Thread读取文件并将其转储到BlockingQueue
  • 其他线程形成队列中的ThreadPooltake()

让我们假设您有一些方法void doMagicStuff(byte[] file)可以对文件做任何事情。

public static void main(String[] args) throws Exception {
    final BlockingQueue<byte[]> processingQueue = new LinkedBlockingQueue<>();
    final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    final AtomicBoolean done = new AtomicBoolean(false);

    IntStream.range(0, Runtime.getRuntime().availableProcessors()).forEach(i -> {
        executorService.submit(() -> {
            while (!done.get() || !processingQueue.isEmpty()) {
                try {
                    doMagicStuff(processingQueue.take());
                } catch (InterruptedException e) {
                    //exit
                    return;
                }
            }
        });
    });

    final Path folder = Paths.get("blah/blah");
    try (final Stream<Path> files = Files.list(folder)) {
        files.filter(Files::isRegularFile)
                .map(file -> {
                    try {
                        return Files.readAllBytes(file);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }).forEach(processingQueue::add);
    }

    done.set(true);
    executorService.shutdown();
    executorService.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
}

public static void doMagicStuff(final byte[] data) {
    //MAGIC MAGIC
}

答案 1 :(得分:0)

我会使用paralelStream()例如

Map<String, String> allFiles =
   Files.walk(Paths.get("dir"))
        .parallel()
        .filter(f -> f.toString().endsWith(".gz"))
        .collect(Collectors.toMap(f -> f.toString(), f -> decryptAndUncompress(f)));
相关问题