java - 如何优雅地停止正在运行阻塞操作的线程?

标签 java multithreading future

我在需要停止的线程中运行阻塞操作:

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/

相关文章:

java - 在OSGI中导入内部包

c# - 如何正确处理 "existing connection forcibly closed"

scala - 依赖 future

asynchronous - 如何有条件地退还不同类型的 future ?

JavaFX - 加载下一个场景时保留工具栏

java - Spring Mvc 应用程序获取 - HTTP 状态 [404] – [未找到]

multithreading - selenium 线程可以安全地使用 Python 进行抓取吗?

dart - Flutter future 如何重跑?

java - 如何使用 Java 从 URL 读取/获取 XML 文件?

java - 可调信号量