我目前正在运行我无法改变的JAR,有时它会因为无缘无故而陷入困境。我试图找到中断线程的方法,停止线程,etceteras,但没有运气。
提供的每个解决方案都是关于完成退出或等待线程完成。
我想要的是简单地在超时完成时关闭线程,然后继续执行程序。
我不想做的是使用带有超时的while循环,java.util.concurrent.Future,System.exit,并进行Thread.interrupt调用。
这些都没有帮助!
答案 0 :(得分:3)
您无法在执行中期强制停止线程。 Thread.destroy()
方法将完成该操作,但它从未实现过,其文档解释了为什么即使它起作用也不安全。
还有一些其他已弃用的方法,例如Thread.stop()
和Thread.suspend()
可能实际上有效,但它们的使用也不安全;再次,他们的文件解释了原因。
告诉线程它应该自行终止,然后等待它这样做,这是阻止线程的唯一安全方法。
作为一种解决方法,您可以在一个完全独立的process中运行您的任务,以便在您希望它停止时destroy。 是安全的,因为进程彼此隔离并且破坏子进程不能使父进程处于不稳定状态。
与单独的进程交互更加困难,因为您不能像使用线程一样在进程之间共享变量。您需要通过流程的输入和输出流发送消息。
答案 1 :(得分:2)
实际上,你无法解决这个问题!
我的意思是:即使你设法杀死"你的"您用来触发第三方代码的线程 - 您有没有方式来杀死由您调用的代码创建的线程或进程。
如果您想绝对确定 kill 所有内容,您可能需要考虑相当复杂的解决方案,例如:
并且认真地说:真正确定第三方图书馆没有任何你无法阻止的东西;您甚至可能必须在某种容器(例如docker实例)中运行该JVM。你可以拆掉并确保一切都消失了。
长话短说:我认为绝对无法控制线程中创建的线程。如果您需要这种级别的控制,您需要考虑外包"那些电话。
答案 2 :(得分:0)
您可以使用Executor
。它允许您submit
个任务(例如runnable
)并并行执行这些任务。此外,一旦您调用shutdown()
,它就可以让您配置超时并杀死所有工作人员(如果他们尚未完成)。一个例子如下:
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.execute(() -> {
//logic to call the method of third party jar
});
//Other business logic
executor.awaitTermination(1, TimeUnit.MINUTES);
executor.shutdownNow();
TimeUnit
是一个枚举,其值为SECONDS
,HOURS
,MINUTES
等(here's javadoc),因此您可以配置不同的时间单位。几点:
shutdownNow
后,不会接受任何新任务(即您无法调用execute
或submit
),现有任务将被停止。所以,我们基本上等待一分钟完成任务,如果不完整,我们就要完成任务。awaitTermination
抛出InterruptedException
(因为如果它们没有完成,它会在内部中断线程),所以你必须将它包装在try-catch
块中。Here执行者的javadoc。