关闭第三个应用程序线程而不等待它完成的首选方法是什么?

时间:2017-04-01 14:23:54

标签: java multithreading

我目前正在运行我无法改变的JAR,有时它会因为无缘无故而陷入困境。我试图找到中断线程的方法,停止线程,etceteras,但没有运气。

提供的每个解决方案都是关于完成退出或等待线程完成。

我想要的是简单地在超时完成时关闭线程,然后继续执行程序。

我不想做的是使用带有超时的while循环,java.util.concurrent.Future,System.exit,并进行Thread.interrupt调用。

这些都没有帮助!

3 个答案:

答案 0 :(得分:3)

您无法在执行中期强制停止线程。 Thread.destroy()方法完成该操作,但它从未实现过,其文档解释了为什么即使它起作用也不安全。

还有一些其他已弃用的方法,例如Thread.stop()Thread.suspend()可能实际上有效,但它们的使用也不安全;再次,他们的文件解释了原因。

告诉线程它应该自行终止,然后等待它这样做,这是阻止线程的唯一安全方法。

作为一种解决方法,您可以在一个完全独立的process中运行您的任务,以便在您希望它停止时destroy 是安全的,因为进程彼此隔离并且破坏子进程不能使父进程处于不稳定状态。

与单独的进程交互更加困难,因为您不能像使用线程一样在进程之间共享变量。您需要通过流程的输入和输出流发送消息。

答案 1 :(得分:2)

实际上,你无法解决这个问题!

我的意思是:即使你设法杀死"你的"您用来触发第三方代码的线程 - 您有没有方式来杀死由您调用的代码创建的线程或进程。

如果您想绝对确定 kill 所有内容,您可能需要考虑相当复杂的解决方案,例如:

  • 而不是仅使用线程,您使用新的JVM B创建新的进程
  • 在该JVM B中,您可以调用该库
  • 但当然,这需要你附加额外的代码;所以"你的" JVM A中的代码可以与"您的" JVM B中的代码
  • 现在你可以拆掉那个过程,以及属于它的所有文物。也许。

并且认真地说:真正确定第三方图书馆没有任何你无法阻止的东西;您甚至可能必须在某种容器(例如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是一个枚举,其值为SECONDSHOURSMINUTES等(here's javadoc),因此您可以配置不同的时间单位。几点:

  • 调用shutdownNow后,不会接受任何新任务(即您无法调用executesubmit),现有任务将被停止。所以,我们基本上等待一分钟完成任务,如果不完整,我们就要完成任务。
  • awaitTermination抛出InterruptedException(因为如果它们没有完成,它会在内部中断线程),所以你必须将它包装在try-catch块中。

Here执行者的javadoc。