如何使用线程池读取多个文件?

hua*_*gjs 3 java multithreading file java-8

我想使用线程池读取多个文件,但失败了。

@Test
public void test2() throws IOException {
    String dir = "/tmp/acc2tid2999928854413665054";
    int[] shardIds = new int[]{1, 2};
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    for (int id : shardIds) {
        executorService.submit(() -> {
            try {
                System.out.println(Files.readAllLines(Paths.get(dir, String.valueOf(id)), Charset.forName("UTF-8")));
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

上面是我写的一个简单示例。它达不到我的目的。

System.out.println(Files.readAllLines(
        Paths.get(dir, String.valueOf(id)), Charset.forName("UTF-8")));
Run Code Online (Sandbox Code Playgroud)

该行将不会运行,也没有警告。不知道为什么

小智 7

您正在提交要执行的任务,然后在等待任务完成之前结束测试。ExecutorService::submit将提交将来要执行的任务并立即返回。因此,您的for循环提交了两个任务,然后结束,并且测试功能在任务有时间完成之前返回。

您可以尝试ExecutorService::shutdown在for循环之后调用,以使执行程序知道所有任务都已提交。然后使用ExecutorService::awaitTermination阻止,直到任务完成。

例如:


    @Test
    public void test2() throws IOException {
        String dir = "/tmp/acc2tid2999928854413665054";
        int[] shardIds = new int[]{1, 2};
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        for (int id : shardIds) {
            executorService.submit(
                    () -> {
                        try {
                            System.out.println(Files.readAllLines(Paths.get(dir, String.valueOf(id)), Charset.forName("UTF-8")));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
        }
        executorService.shutdown();
        executorService.awaitTermination(60, TimeUnit.SECONDS); //Wait up to 1 minute for the tasks to complete
    }
Run Code Online (Sandbox Code Playgroud)