【问题标题】:How can I create multithreaded code using ThreadpoolExecutor & Callable Future如何使用 ThreadpoolExecutor 和 Callable Future 创建多线程代码
【发布时间】:2021-11-20 18:52:03
【问题描述】:

我有一个执行方法,它一个一个地运行多个测试用例,测试用例在一个字符串数组列表中传递。

我正在尝试以多线程方式运行此测试用例,同时将数据并行写入 CSV 文件。

这是我所做的,但似乎代码没有以多线程方式工作。我在newFixedThreadPool() 中传递了nThread 2,5,7,但执行代码需要相同的时间。

private void executeTest(List<String[]> inputArray) throws ExecutionException, InterruptedException {

    ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(nThreads);//2, 5, 7
    long start = System.currentTimeMillis();
    for (String[] listOfArray : inputArray) {

        Callable c2 = new Callable() {
            public ApiResponse call() {
                response = runTestCase(listOfArray);                    
                try {
                    csvWriter.writeCsv(listOfArray[0], response);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                return response;
            }
        };
        System.out.println("nThread :"+nThreads);
        Future<ApiResponse> result = executor.submit(c2);
        result.get();

    }
    long stop = System.currentTimeMillis();
    long timeTaken = stop - start;
    System.out.println("Total time taken :"+timeTaken+"No of Theads :"+nThreads);

}

【问题讨论】:

  • 将数组列表称为“inputArray”,而将数组本身称为“listOfArray”,这是一种误导。
  • 请注意,为 IO 添加更多线程可能不会减少花费的时间,如果您按照我的回答进行调整,csvWriter 需要是线程安全的。
  • 是的,csvWriter 是线程安全的。

标签: java multithreading csv callable


【解决方案1】:

对未来 result.get(0) 的调用会一直阻塞,直到操作完成,因此您只是在循环中一一执行任务 - 即使它们由执行程序服务在不同线程上执行。

// result.get();

改为删除上面的行并在最后等待终止,以便池中的全部线程可以同时接收任务,例如:

// All task submitted, mark for shutdown (only call after ALL submits done)
executor.shutdown();

// Wait for the executor service to finish
// You should consider how long this should be:
if (!executor.awaitTermination(whateverTimeIsReasonable, TimeUnit.SECONDS))
    throw new RuntimeException("Test failed");

隐藏异常的测试对测试没有帮助,改变这一点:

e.printStackTrace();

throw new UncheckedIOException(e); 将确保报告所有错误。

【讨论】:

  • 完成后在线程池上调用shutdown也很重要,否则线程永远不会被清理。
  • @DuncG 我们如何在这段代码中使用 CountDown 锁存器?
  • 只需在循环前添加latch = new CountDownLatch(inputArray.length),在任务内添加latch.countDown(),在循环后添加latch.await()
猜你喜欢
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
  • 2017-10-07
  • 2013-02-21
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多