【问题标题】:treating of asynchronous executor shutdown when waiting on future等待未来时异步执行器关闭的处理
【发布时间】:2018-05-05 11:14:57
【问题描述】:

我有一个 ssh 客户端库实现。每个连接都有几个执行者。一种是使用 ScheduledThreadPoolExecutor 的线程池,用于对短期任务和计时器进行排队。一个是读执行器,用于持有一个数据包接收任务。一种是写执行器,串行执行任务,每个任务向服务器发送一个数据包。当然 read 和 write executor 都是单线程的,write executor 就像消息队列一样使用。

我遇到的问题是:排队消息的方法和排队任务的一些方法返回一个 CompletableFuture。我使用 CompletableFuture.runAsync 方法排队。但是,连接可能会以有序或强制的方式异步关闭。在这种情况下,使用 shutdownNow 方法关闭部分或所有池。

如果某些线程(包括这些池之外的线程)可以等待某些任务同步完成,并且由于包括网络错误在内的所有原因而存在异步关闭的风险,该怎么办? shutdownNow 不会发出未来的取消方法。我不关心实际任务是否被中断,我只关心如果执行程序在他们的任务仍在队列中时关闭,futures 会无限期地阻塞。

处理这种情况的最佳做法是什么?人们做什么/等等?

【问题讨论】:

    标签: java multithreading asynchronous executor


    【解决方案1】:

    好的,我相信我有一个想法。如下:

    因为并行关闭等待所有任务完成,而shutdownNow只会丢弃它们而不取消,而且因为我实际上一直使用可完成的期货,所以我决定为每个连接维护一组各种可完成的期货,这将保存所有任务,包括消息发送者和提交到任务池的正常任务。每个关闭连接或开始有序断开连接的方法都将通过集合并异常完成所有期货,但有一些例外。这比取消提供更好的错误。如果任务以这种方式自行取消,也不会发生任何事情。

    我没有使用runAsync,或者在任务与runnables无关的情况下通常创建一个可完成的未来,我有一个特殊的方法来创建这样一个任务,将它添加到集合中,并使用CompletableFuture.whenCompleted()附加一个函数,如果任务因任何原因完成,则将其从集合中移除。我也有 runAsync,它使用前面描述的方法创建任务,然后使用 CompletableFuture.completeAsync 提交一个 runnable。

    这样,所有等待的线程都应该在连接关闭时解除阻塞,并从包括发送消息在内的所有任务中获得一个很好的异常,无论我使用哪种方法等待完成,get() 或 join()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      • 2021-09-30
      • 1970-01-01
      • 2022-01-02
      • 2021-11-01
      • 1970-01-01
      相关资源
      最近更新 更多