【问题标题】:Stopping (interrupting) a thread that is running a blocking action?停止(中断)正在运行阻塞操作的线程?
【发布时间】:2020-10-05 20:45:25
【问题描述】:

与这个问题类似,但在细节上有所不同:Interrupting a thread that waits on a blocking action?

有一个我无法控制的 3pty 库,这个库有一个方法pressButtonAndHoldIt(long duration)。这是一种阻塞方法,这意味着如果您将duration 设置为 10 分钟 - 它将执行 10 分钟(无中断)的操作。 我从一个单独的线程中使用这个方法,所以我可以在“按住按钮”的同时做其他事情:

final Future<?> f = Executors.newSingleThreadExecutor().submit(() -> {
  3ptyLibrary.pressButtonAndHoldIt(Duration.ofMinutes(10).toSeconds());
});

var stuff = myOtherStuff();
//here I want to stop what was submitted in "f", e.g. "f.forceStop()"

通常myOtherStuff() 大约需要 9 分钟,但有时可能需要 5 分钟,所以我想停止那个阻塞的后台进程。我该怎么做?

请注意,Executors.newSingleThreadExecutor().submit() 只是一个示例:我可以在 java 中以任何方式创建后台线程(如果有帮助的话)。

【问题讨论】:

  • 没有什么可以阻止第三方方法的执行,除非它已经被编程为响应中断。

标签: java multithreading


【解决方案1】:

您唯一能做的就是致电thatThreadRef.interrupt(); 并祈祷。

interrupt() 所做的是“提高中断标志”。这只完成了两件事:

  • 所有明确指定要查看的方法都会,嗯,查看: 很容易识别 em:它们都是指定抛出 InterruptedException 的方法,例如 Thread.sleep。如果在您调用它们时标志已启动,这些方法将立即返回(通过抛出 InterruptedException),而根本不会休眠。如果你在他们睡觉的时候打断线程,他们也会通过抛出它立即退出。
  • 对于所有其他情况,它只是... 引发中断标志。就是这样。

现在,第二件事并不是完全没用:一个方法可以不时检查它并采取相应的行动,做任何看起来合适的事情(关于你应该做什么,并没有多少实际的语义标准做。只要您返回或以其他方式中断某事)。例如,在大多数操作系统(但不是所有操作系统)上,读取文件(指定抛出InterruptedException)可能会阻塞,如果你打断它,通常这确实有效并中止读取,导致IOException 发生。关键是,JVM 并不能保证它(嘿,如果你必须在架构和操作系统的组合爆炸上运行,你就必须轻描淡写地保证)。

所以,这就是你的计划:祈祷这个 pressButtonAndHoldIt 能看到它。

如果没有,您几乎无法直接执行任何操作。那时你最好的选择是,如果图书馆真的不支持它(不是通过中断也不是以任何其他方式)并且你不能编辑源代码或提供更新的拉取请求,那就是开始一个全新的JVM 中的 JVM(不容易),然后硬杀死它以尝试“中止”该阻塞操作。这本身可能不起作用(在这种情况下,这是一个非常糟糕的库,如果它的 VM 死了会泄漏资源)。那是一把能杀死这种特殊蚊子的大枪,但它是你唯一拥有的。

【讨论】:

    猜你喜欢
    • 2013-07-05
    • 2012-09-01
    • 2019-09-02
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-10
    • 1970-01-01
    相关资源
    最近更新 更多