【问题标题】:Awaiting termination of multiple ExecutorServices for a fixed time period在固定时间段内等待多个 ExecutorServices 终止
【发布时间】:2015-11-10 16:22:20
【问题描述】:

我有以下包装器,它公开了ExecutorServiceawaitTermination 方法

public class AwaitableTermination {
    protected final ExecutorService executorService;

    public AwaitableTermination(ExecutorService executorService) {
        this.executorService = executorService;
    }

    public boolean awaitTermination(long timeout) throws InterruptedException {
        return executorService.awaitTermination(timeout, TimeUnit.MILLISECONDS);
    }
}

典型输入为 500 毫秒。用户了解这些时间是近似值。

我对扩展AwaitableTerminationCompositeAwaitableTermination 类有一个新要求,其中包含ExecutorService 对象的列表。如果所有ExecutorService 对象在输入时间范围内终止,awaitTermination 应该返回true,否则false

我可以将每个ExecutorServiceawaitTermination 放在自己的线程中,但这似乎非常浪费,更不用说不精确了(不能保证所有线程都会及时执行)。

一种可能的单线程方法是遍历ExecutorServices 并根据每个对象减少超时

private final List<ExecutorService> services;

public boolean awaitTermination(long timeout) throws InterruptedException {
    Queue<ExecutorService> queue = new ArrayDeque<>(services);
    long start = System.currentTimeMillis();
    boolean result = true;
    ExecutorService service = null;
    while(result && (service = queue.poll()) != null) {
        long currentTimeout = timeout - (System.currentTimeMillis() - start);
        if(currentTimeout > 0) {
            result = service.awaitTermination(currentTimeout, TimeUnit.MILLISECONDS);
        } else {
            result = false;
        }
    }
    return result;
}

但是,这种方法让我觉得对于 ExecutorServices 的较大集合非常容易出错(目前我预计 services 集合中的对象不超过 4 个,但我不想这样做依赖这个假设)。有没有更精确/优雅的方法来做到这一点?

【问题讨论】:

    标签: java multithreading time executorservice


    【解决方案1】:

    我认为这段代码没有问题。

    如果你有 大量的集合(比如 100k+)ExecutorService,你应该更关心实际的线程数!

    awaitTermination 如果服务已经关闭或者没有任务挂起,并且如果您有很多 ExecutorService 运行很可能是这种情况,否则您的系统应该已经受到影响。因此,即使对于大型集合,这段代码也不应该有任何问题。

    【讨论】:

    • 我担心我会因为循环开销而得到误报。假设循环迭代至少需要 1ms(对于终止的ExecutorService);给定 500 毫秒的超时,超过 50 个 ExecutorServices 的集合,以及在 450 毫秒后返回 true 的初始 ExecutorService,即使所有 ExecutorServices 都因超时而终止,该方法也将返回 false (在第一次迭代后减少到 50 毫秒)将在每次迭代时递减 1 毫秒,并在最后一次迭代之前到期。但我可能高估了循环开销。
    猜你喜欢
    • 1970-01-01
    • 2014-07-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2014-12-29
    • 2020-04-21
    相关资源
    最近更新 更多