我最近了解了这个Java 1.5功能,并开发了一个示例代码来使用它。我的目标是在线程因未捕获的异常而死亡时重新启动线程。
public class ThreadManager {
public static void main(String[] args) throws InterruptedException {
startThread();
}
public static void startThread(){
FileReaderThread reader = new FileReaderThread("C:\\Test.txt");
Thread thread = new Thread(reader);
thread.setUncaughtExceptionHandler(new CustomExceptionHandler());
thread.start();
}
}
这里的文件阅读器只包含一个读取文件和打印内容的例程。我通过在该类中使文件名为null来模拟未捕获的异常。
然后我的CustomExceptionHandler类如下。
public class CustomExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
ThreadManager.startThread();
}
}
但在这里我发现了一个问题。在未捕获的异常之后,线程处于休眠状态。我使用分析器验证了它。所以创建新线程会随着时间的推移填满我的记忆。使system.gc()后跟t = null不起作用。
那么您建议处理此方案的最佳方法是什么?我只需要一个新线程,我不再需要任何旧线程....
由于
答案 0 :(得分:4)
我建议的方法是不要让异常从你的线程中泄漏出来。未捕获的异常处理程序是一个非常好的工具,但是,如果您使用它来确保您的线程正在运行,我建议您有设计或代码问题。你的线程正在死于一场可怕的死亡而只是忽略了它并且重新启动它可能不是你想要做的,即使你能够找出睡眠线程问题。
想象一下,而不是在你的线程中,问题在于你的main()
方法 - 你是否会让同样的异常一直泄漏并杀死你的应用程序?如果没有,你会采取什么措施来缓解这个问题?你不会写一个再次调用main()
的异常处理程序吗?无论你做什么,这都是你应该在你的线程中做的。
答案 1 :(得分:1)
您不应重新启动即将退出的线程。当给定线程终止时,该方法被调用。所以你只能创建并启动一个新线程。如果您了解threads类(通过instanceof ...),您可以从中获取runnable并在终止线程组中创建一个新线程,并从UncaughtExceptionHandler中启动它。
但是请注意:我会检查具体的例外情况。最小值可以是:只有当throwable是运行时异常时才重启,而不是错误!