我有一个ssh客户端库实现。每个连接都有很少的执行程序。一个是使用ScheduledThreadPoolExecutor的线程池,用于对短期任务和计时器进行排队。一个是读执行器,用于保存数据包接收器任务。一个是写执行器,串行执行任务,每个任务都向服务器发送一个数据包。当然,读取和写入执行程序都是单线程的,而写入执行程序则用作消息队列之类的东西。
我遇到的问题是:对消息进行排队的方法,以及一些排队任务的方法,返回一个CompletableFuture。我使用CompletableFuture.runAsync方法排队。但是,可以以有序或强制的方式异步关闭连接。在这种情况下,使用shutdownNow方法关闭部分或全部池。
如果某些线程(包括这些池之外的线程)可能等待某个任务同步完成,并且由于包括网络错误在内的所有事情而存在异步shutdownNow的风险,该怎么办? shutdownNow不会发出future的cancel方法。我不关心实际任务是否被中断,我只关心如果执行者在他们的任务仍然在队列中时被关闭,期货将无限期地阻止。
处理这种情况的最佳做法是什么?人们做什么/等?
答案 0 :(得分:0)
好的,我相信我有个主意。它是以下内容:
因为并行关闭等待所有任务完成,并且shutdownNow只是将它们删除而不取消,并且因为我实际上最终总是使用可完成的期货,所以我决定维持一组每个连接的各种可完成的期货,这将包含所有任务,包括提交到任务池的消息发送者和正常任务。关闭连接或开始有序断开连接的每种方法都将通过集合并完成所有期限,但有一些例外情况。这比错误提供更好的错误。如果任务以这种方式取消,也不会发生任何事情。
我没有使用runAsync,或者通常在没有与runnables相关联的任务的情况下创建可完成的未来,我有一个特殊的方法来创建这样的任务,将它添加到集合中,并使用CompletableFuture.whenCompleted()附加函数,如果由于任何原因完成任务,则从集合中删除任务。我也有runAsync使用前面描述的方法创建任务,然后使用CompletableFuture.completeAsync提交runnable。
这样所有等待的线程都应该在连接关闭时解除阻塞,并从包括已发送消息在内的所有任务中获得一个很好的异常,无论我用哪种方法等待完成,get()或join()。