无法从TimerTask线程中捕获异常

时间:2012-07-12 08:53:04

标签: java multithreading

我有一个Java类,它在main方法中启动TimerTask,扩展TimerTask的类是一个内部类(Class myTimer扩展TimerTask)。在它的run方法中,myTimer抛出一个异常,在main方法中我试图捕获这样的异常:

try {
  timer.schedule(new myTimer(arg1, arg2), 0, RETRY_PERIOD);
} catch (Exception e) {
     System.out.println("Exception caught");
}

但这不起作用,它永远不会捕获异常,myTimer线程抛出。任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:2)

Timer将在添加它的线程的不同线程中执行TimerTask.run()方法,父类无法捕获的主方法抛出异常。

一种可能的解决方案是防止异常传播出run()方法,并通过某种查询方法向父级提供任何有用的信息。在查询结果之前,父级将需要等待run()方法完成。

答案 1 :(得分:2)

您的情况有点棘手,我不确定您希望在您的代码段中发生什么。你期望主线程阻塞,直到计时器线程抛出异常?因为那不会发生。 try-catch唯一能做的就是捕获schedule调用中发生的异常,而不是定期执行线程执行的代码。

无论如何都没有意义。由于计时器线程可以与主线程并行抛出异常,因此您需要定期冻结主线程以检查异常或永久冻结它直到计时器结束。

后一种情况可以通过ScheduledThreadPoolExecutor

轻松完成
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
ScheduledFuture f = exec.scheduleWithFixedDelay(new Task(arg1, arg2), 0, 
                                   RETRY_PERIOD, TimeUnit.MILLISECONDS);

...
try {
    f.get(); // wait for task to finish
} catch(ExecutionException ex) {
    System.out.println("Exception caught");
}

其中Task是一个实现Runnable的类。

当然,这将阻止主线程,直到任务返回或抛出异常(可能永远不会发生)。或者,您可以使用定时get来定期检查异常。