简体   繁体   English

使用 ExecutorService 并行化和监控任务

[英]Parallelize and monitor tasks with ExecutorService

I have a function/task void task() that needs to be called about 4-6 million times.我有一个函数/任务void task()需要调用大约 4-6 百万次。
I want to parallelize this operation over threads in a thread pool.我想在线程池中的线程上并行化这个操作。
I do not care about the return value of the tasks so I can avoid messing around with Future<T> .我不关心任务的返回值,所以我可以避免弄乱Future<T>
I want to periodically poll the status of how the threads are coming along.我想定期轮询线程如何进行的状态。 The status is simply how many invocations of task() returned cleanly and how many threw an exception.状态只是干净地返回了多少task()调用以及有多少引发了异常。

Here's what I came up with:这是我想出的:

class Test {
    AtomicInteger success = new AtomicInteger(0);
    AtomicInteger failed = new AtomicInteger(0);
    CountDownLatch latch = new CountDownLatch(1_000_000);

    private void start() {
        ExecutorService executorService = Executors.newFixedThreadPool();
        for (int i = 0; i < 1_000_000; i++) {
          executorService.execute(this::task);
        }
        while (!countDownLatch.await(1, TimeUnit.SECONDS)) {
          log("Success: %d Failed: %d", success.get(), failed.get());
        }
        log("===================== Final tally =====================");
        log("Success: %d Failed: %d", success.get(), failed.get());
        executorService.shutdown();
    }

    private void task() {
        try {
           doSomeStuff();
           success.incrementAndGet()
        } catch(Exception e) {
           failed.incrementAndGet();
        }
        countDownLatch.countDown();
    }
}

Two AtomicInteger that the threads use to record successes or failures and a CountDownLatch that the "monitor" thread uses to check on the progress.线程用来记录成功或失败的两个AtomicInteger和一个“监控”线程用来检查进度的CountDownLatch

Is there a more idiomatic way to do this?有没有更惯用的方法来做到这一点? Some thing that doesn't involve submitting millions of Runnable lambdas to the ExecutorService perhaps?一些不涉及向ExecutorService提交数百万个Runnable lambda 的事情?

I could put the whole thing in an我可以把整个东西放在一个

IntStream.range(0, 1_000_000).parallelStream().map(...).groupBy(...)

but I won't be able to monitor the progress.但我将无法监控进度。

If you want to use stream as you proposed, you can move your monitoring part into another thread like this:如果您想按照您的建议使用 stream ,您可以将监控部分移动到另一个线程中,如下所示:

new Thread(()->{  
 while (!countDownLatch.await(1, TimeUnit.SECONDS)) {
          log("Success: %d Failed: %d", success.get(), failed.get());
        }
        log("===================== Final tally =====================");
        log("Success: %d Failed: %d", success.get(), failed.get());
}).start()

IntStream.range(0, 1_000_000).parallelStream().map(...).groupBy(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM