我在需要停止的线程中运行阻塞操作:
Future serverFuture = Executors.newCachedThreadPool().submit(() -> {
var serverSocket = new ServerSocket(Config.SERVER_PORT);
serverSocket.accept(); // <-- blocking
});
serverFuture.cancel(true);
通常,我会实现一个循环,不断检查线程是否被中断并最终停止它。但是,由于线程在 serverSocket.accept()
方法中被阻塞,因此这是不可能的。
克服这个问题的通常方法是什么?
最佳答案
How to gracefully stop a thread that is running a blocking operation?
一般来说,你不能。但是对于某些特定 操作,您可以做一些事情。例如,您可以尝试中断线程。在像您的示例这样的情况下,您无法直接访问正在运行任务的 Thread
,您可以使用 Future.cancel()
:
serverFuture.cancel(true);
但是阻塞操作不一定会在线程中断时被中断。那些这样做的通常被记录为抛出 InterruptedException
,并且这不在 ServerSocket.accept()
声明抛出的异常中。特别是对于该方法,您最好的选择可能涉及使用 ServerSocket.setSoTimeout()
为 accept()
将阻止的时间量设置一个合适的上限。使用相对较短的超时并在循环中执行 accept()
将允许您定期检查是否要中止任务。
总的来说,您需要选择适合您要取消的工作的策略,并且您可能需要花费一些设计精力来使该任务完全可以中断。
关于java - 如何优雅地停止正在运行阻塞操作的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54391645/