执行者与线程

时间:2012-10-09 22:12:06

标签: java multithreading executorservice

我正在尝试运行以下代码:

public static void main(String[] args){
    ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);

    Runnable r = new Runnable() {
        @Override
        public void run() {
            throw new RuntimeException();
        }
    };
    service.execute(r );
    ScheduledFuture<?> schedule = service.schedule(r, 0, TimeUnit.SECONDS);
    new Thread(r).run();
}

关于上述问题,我有以下问题:

  1. 有没有办法捕获并响应执行程序线程上发生的异常?
  2. 为什么创建的线程的异常显式传播到主线程,但是使用执行器服务的两次执行都不会传播该错误?怎么能发现这个错误?
  3. 编辑:进一步的问题浮现在脑海中:

    1. 如何停止我安排的定期任务,让我们说N次重复或N分钟后?

2 个答案:

答案 0 :(得分:7)

问题2非常简单 - 你实际上并没有开始新的线程,你只是调用run(),它在原始线程中同步运行。您应该调用start(),此时不会传播回来。

至于处理ScheduledExecutorService中的异常 - 如果你调用Future.get(),如果原始任务引发异常,则会抛出ExecutionException,将原始异常暴露为原因:

  

尝试检索因抛出异常而中止的任务的结果时抛出异常。可以使用Throwable.getCause()方法检查此异常。

如果你需要在没有阻止的情况下回复异常以便将来完成,你可以将你的“真实”Runnable包装到另一个刚刚委派给原始版本run()的{​​{1}}中。方法,但使用适当的try / catch块。

答案 1 :(得分:6)

你可以这样抓住它:

    ScheduledFuture<?> schedule = service.schedule(r, 0, TimeUnit.SECONDS);
    try {
        Object get = schedule.get();
    } catch (InterruptedException ex) {
        ex.printStackTrace();
    } catch (ExecutionException ex) {
        ex.printStackTrace();
    }

如果代码在(Scheduled)ExecutorService throws中运行,则会在调用Future.get() ExecutionException

时将其重新抛出

编辑:

关于停止计划任务,已经discussed and solved