通知调用方法有关线程中发生的异常

时间:2014-12-08 10:12:17

标签: java multithreading spring-mvc exception-handling

我正在编写一个Spring-mvc应用程序。

我正在使用ThreadPoolTaskExecutor执行任务。

我有以下示例代码。

MyClass.java

public class MyClass {
    public void startProcess() {
        ThreadPoolTaskExecutor taskExecutor = //Initializing 
        for (int i = 1; i <= 5; i++) {
            taskExecutor.execute(new MyRunnable());
            // I can call taskExecutor.submit(task); also, if required
        }
    }
}

MyRunnable.java

public class MyRunnable implements Runnable {

    @Override
    public void onRun() {
        try {
            //Code which generates exception like below
            throw new Exception("Runtime Exception");
        } catch (Exception e1) {
            // log or throw the exception
        }
    }
}

我想通知startProcess()有关MyRunnable的运行方法中发生的异常。

任何人都可以为此指导我。

我在下面找到了链接,但它没有解决我的问题。

感谢。

修改

还有一个问题。如果我使用@Async异步调用我的其他方法,如果我想检查异步方法中发生的异常,那我该怎么办? async方法也会返回未来的对象。

回答我从here

获得的@Async问题

2 个答案:

答案 0 :(得分:1)

你可以在你的Thread中添加带有一些监听器的构造函数。

像:

的ExceptionListener:

  public class ExceptionListener{
    public void doSomething(long threadId,Exception e){
      //...e.g., notify startProcess()
    }
  }

MyRunnable:

  public class MyRunnable implements Runnable {
    private ExceptionListener listener;

    private MyRunnable(ExceptionListener exception) {
      this.listener = listener;
    }

    @Override
    public void run() {
      //...
      listener.doSomething(Thread.currentThread().getId(),new Exception("Runtime Exception"));
      //...
    }
  }

startProcess():

  public void startProcess() {
    ThreadPoolTaskExecutor taskExecutor = //Initializing 
    ExceptionListener listener= new ExceptionListener();
    for (int i = 1; i <= 5; i++) {
        taskExecutor.execute(new MyRunnable(listener();
        // I can call taskExecutor.submit(task); also, if required
    }
  }

或者,你可以使用 Thread.UncaughtExceptionHandler ,就像描述here一样。

<强>编辑。

澄清:

  

如果发生异常,我必须停止进一步执行其他操作   流程。所以我想抓住或获得有关异常的通知   startProcess方法。 - Naman Gala 1小时前

答案:

  

我认为你的工作线程会有循环。所以你可以传递volatile   boolean 到每个线程并将其设置为true或   如果出现异常,则循环条件将为此布尔值   变量。 - Maksym 58分钟前

答案 1 :(得分:1)

而不是Runnable,实施CallableCallable可以抛出异常,当您使用Future检索Callable的结果时,您将获得以ExecutionException抛出的异常:

public class MyCallable implements Callable<Void> {
    public Void call() throws Exception {
        try {
            //Code which generates exception like below
            throw new Exception("Runtime Exception");
        } catch (Exception e1) {
            // log or throw the exception
        }
        return null; // To satisfy the method signature
    }
}

在MyClass中:

List<Future<Void>> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
    Future<Void> future = taskExecutor.submit(new MyCallable());
    futures.add(future);
}

// After all tasks have started, now wait for all of them to complete (they run in parallel)
// and check if there were any exceptions

for (Future<Void> future : futures) {
    try {
        future.get();
    } catch (ExecutionException e) {
        // Access the exception thrown by the different thread.
        e.getCause().printStackTrace();
    }
}