执行者与线程

Bob*_*r02 4 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();
}
Run Code Online (Sandbox Code Playgroud)

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

  1. 有没有办法捕获并响应执行程序线程上发生的异常?
  2. 为什么创建的线程的异常显式传播到主线程,但是使用执行程序服务的两个执行都不会传播该错误?怎么能发现这个错误?

编辑:进一步的问题浮现在脑海中:

  1. 如何停止我安排的特定周期性任务,比如在N次重复或N分钟之后?

Jon*_*eet 7

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

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

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

如果您需要响应异常而不阻塞以便将来完成,您可以将您的"真实"包装Runnable在另一个刚刚委派给原始run()方法的情况下,但使用适当的try/catch块.

  • @ Bober02:真的,使用`Future.get()`是关于它的.毕竟,你不希望原始线程在任意时间点抛出异常,不是吗? (2认同)

lin*_*ski 6

你可以像这样抓住它:

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

如果运行的代码(Scheduled)ExecutorService 抛出异常,则在调用Future.get()wrapped 时将重新抛出ExecutionException

编辑:

关于停止计划任务,已经讨论并解决了.