3

我在我们的生产环境中遇到了特殊情况,其中一段特定的代码进入了无限循环。原因主要是数据特定的,无法找出真正的原因。同时,我希望做的是产生一个单独的子线程来执行那段代码,如果它执行超过 30 秒,想要阻止该子线程执行

Thread t = new Thread() {
    public void run() {
                    // This is where i will the method that runs in a infinite loop
                    callMethodThatRunsInInfiniteLoop();
    };
};

t.start();
try {
    t.join(2000); // wait 2s
} catch (InterruptedException e) {
    e.printStackTrace();
} 

// if not completed how to break the child thread ???
4

4 回答 4

1

有没有办法通过抛出异常来导致无限循环代码中断?例如将一些变量设置为空?一个可能的优点是受影响的线程(如果写得好)将在自己之后清理并关闭比 stop() 更好。

于 2012-08-08T23:13:36.303 回答
1

不幸的是,它是第三方代码,无法轻易更改。

听起来您正在尝试解决第三方库中的问题……或者在您的代码中调用第三方库时输入错误或其他问题。

我的建议是解决这个问题,而不是试图杀死错误的线程。如果你不能这样做,那么你有两个选择:

  • 修改 3rd 方库以感知中断/响应,然后使用它来停止它,或者

  • 尝试找到一种方法来“进入”第 3 方库的数据结构(例如使用令人讨厌的反射)并使其死亡。

如果您求助于后者,那么也许您还应该考虑在单独的 JVM 中运行 3rd 方库,以便您可以使用 Process API 强行杀死它。


Thread.stop()话虽如此,实际上(可能)可以安全使用的情况有限。基本上,如果错误线程不创建子线程,不与其他线程交互并且不共享数据结构,并且当你杀死它时不能进行类初始化,那么你可能会是安全的。问题是有太多的理论场景,停止线程可能会导致损坏,很难知道您已经考虑了所有这些场景。

于 2012-08-09T00:40:54.490 回答
0

根据方法的实现,您可以在它自己的 JVM 中启动它,然后通过调用destroy()进程来停止它:

Process process = new ProcessBuilder("java", "-cp", "/some/class/path", "com.mycompany.MyLauncher").start();

// sometime later
process.destroy();
于 2012-08-09T00:27:52.500 回答
0

所有用于“纯粹在外部”停止线程的方法都已弃用并被认为是不安全的。可以安全停止线程的唯一方法需要

  1. 修改正在运行的代码以检查是否已通过stopMe设置某些变量礼貌地要求停止;或者
  2. 选择另一个线程已经使用的变量来导致线程退出(这通常是非常糟糕的做法);例如,按照 user949300 的建议,强制它抛出异常。

没有这个,你别无选择,只能使用不安全的方法,这意味着Thread.stop(),这也是非常糟糕的做法。这是一个非常糟糕的主意,当然唯一真正的解决方案是更改您的输入以防止这种情况发生,或者修复第三方代码。

线程使用的任何对象都可能处于不一致(并且可能不可用)的状态,所以尽量避免让线程修改任何重要的东西,如果可以帮助它,不要查看它的任何输出变量。

Thread.stop()方法似乎仍然存在于 Java SE 7 中,尽管当然已弃用,但我不能保证您的特定环境。

请参阅http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

于 2012-08-08T23:46:20.893 回答