addShutdownHook和setUncaughtExceptionHandler在java中无法正常工作

时间:2010-02-26 10:47:04

标签: java multithreading exception-handling shutdown

我有一个多线程程序,我有一个线程可以监视多个线程。功能设计如下:

主程序启动并启动Watcher Thread,在void Main()中,我有一行

Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener"));

当我没有启动观察者线程时,在我终止程序时调用ShutdownThread,但是当我启动其中有死循环的Watcher线程时,不调用ShutdownThread (我在那个帖子中打印出一条消息)。这非常奇怪。有什么解释吗?

观察者线程如下:

public void run(){
   boolean running=false;
   thread a=new thread(...); //Do the same thing for b, c, d...
   while(true){
   if (a.isActive()){
     if (running)
        thread a= new thread(...);
     a.start();
     running=true;
   }
   Thread.sleep(1000); //try catch block...
}

我想要的是一个正常的关闭,在获得终止信号时,运行shutdownThread,设置一个标志并中断所有线程,并等待线程中断它,或者它超时以便剩下的线程可以是杀害。所有线程都可以捕获一个中断,并检查是否设置了一个标志,如果设置,它将中断shutdownThread然后退出自己。相反,我所看到的是所有线程都自行终止,根本不进行清理。

如何使用信号?那有什么好的跨平台代码吗?

然后,setUncaughtExceptionHandler也不起作用。我做了测试,发现根本没有调用处理程序。我不知道为什么。处理程序的代码是:

    public static class ErrHandler implements Thread.UncaughtExceptionHandler{
    public final void uncaughtException(Thread t, Throwable e) {
            Error(t + "died, threw exception: " + e);
        }
    }//this is in public class globals

我用

挂钩
producer.setUncaughtExceptionHandler(Globals.errhandler);

在我的代码中,我只看到原来的e.printStack()而不是。似乎我无法在父线程或其自身中覆盖它。这太令人沮丧了。我正在考虑将一个Entry放入队列,并在其他地方读取它。至少这可能有效。

哦,目的是确保如果任何线程因运行时异常而死亡,则观察者线程将检查异常是否足够致命,并决定重新启动该线程或完全退出。同时,我希望程序优雅地结束(当用户结束时,中断被发送到保护程序线程,以便将结果转储出来,然后中断回来告诉我们已准备好退出)。

1 个答案:

答案 0 :(得分:0)

Dunno如果它可以帮到你,但我们遇到了同样的行为。 并非所有异常都正确地路由到已注册的ExceptionHandler。

我想知道并发框架是否存在单元测试。因为必须检测到这一点。

我们通过使用ScheduledExecutorService实例作为委托来实现ScheduledExecutorService,并在Runnable / Callable实现中封装每个方法的Runnable / Callable参数,以纠正行为。