从Java ExecutorService捕获线程异常 [英] Catching thread exceptions from Java ExecutorService

查看:93
本文介绍了从Java ExecutorService捕获线程异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发用于并行计算的软件开发框架 JavaSeis.org 。我需要一个强大的机制来报告线程异常。在开发过程中,了解异常来源的具有高价值,所以我想错过过度报告。我也希望能够处理线程中的Junit4测试。方法是否合理或有更好的方法?

  import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestThreadFailure {

public static void main(String [] args){
int size = 1;
ExecutorService exec = Executors.newFixedThreadPool(size);
ThreadFailTask​​ worker = new ThreadFailTask​​();
未来<整数> result = exec.submit(worker);
try {
整数值= result.get();
System.out.println(Result:+ value);
} catch(Throwable t){
System.out.println(Caught failure:+ t.toString());
exec.shutdownNow();
System.out.println(Stack Trace:);
t.printStackTrace();
返回;
}
抛出新的RuntimeException(没有抓到失败!!);
}

public static class ThreadFailTask​​ implements Callable< Integer> {
@Override
public Integer call(){
int nbuf = 65536;
double [] [] buf = new double [nbuf] [nbuf];
return new Integer((int)buf [0] [0]);
}
}
}


解决方案

我不相信当使用 submit()时,有一个标准的钩子来获取这些异常。但是,如果您需要支持 submit()(这听起来很合理,鉴于您使用 Callable ),您可以随时包装Callable和Runnable:

  ExecutorService executor = new ThreadPoolExecutor(1,10,60,TimeUnit.SECONDS,new LinkedBlockingDeque< ; Runnable>()){
@Override
public< T>未来< T>提交(最终可调用< T>任务){
可调用< T> wrappedTask = new Callable< T>(){
@Override
public T call()throws异常{
try {
return task.call();
}
catch(异常e){
System.out.println(哦,男孩,有东西破了!);
e.printStackTrace();
throw e;
}
}
};

返回super.submit(wrappedTask);
}
};

当然,这个方法只有在你建立 ExecutorService 首先。此外,请记住覆盖所有三个 submit()变体。


I'm working on a software development framework for parallel computing JavaSeis.org. I need a robust mechanism for reporting thread exceptions. During development, knowing where exceptions came from has high value, so I would like to err on the side of over-reporting. I would also like to be able to handle Junit4 testing in threads as well. Is the approach below reasonable or is there a better way ?

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestThreadFailure {

  public static void main(String[] args) {
    int size = 1;
    ExecutorService exec = Executors.newFixedThreadPool(size);
    ThreadFailTask worker = new ThreadFailTask();
    Future<Integer> result = exec.submit(worker);
    try {
      Integer value = result.get();
      System.out.println("Result: " + value);
    } catch (Throwable t) {
      System.out.println("Caught failure: " + t.toString());
      exec.shutdownNow();
      System.out.println("Stack Trace:");
      t.printStackTrace();
      return;
    }
    throw new RuntimeException("Did not catch failure !!");
  }

  public static class ThreadFailTask implements Callable<Integer> {
    @Override
    public Integer call() {
      int nbuf = 65536;
      double[][] buf = new double[nbuf][nbuf];
      return new Integer((int) buf[0][0]);
    }
  }
}

解决方案

I don't believe there is a standard 'hook' to get to these exceptions when using submit(). However, if you need to support submit() (which sounds reasonable, given that you use a Callable), you can always wrap the Callables and Runnables :

ExecutorService executor = new ThreadPoolExecutor(1, 10, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()) {
    @Override
    public <T> Future<T> submit(final Callable<T> task) {
        Callable<T> wrappedTask = new Callable<T>() {
            @Override
            public T call() throws Exception {
                try {
                    return task.call();
                }
                catch (Exception e) {
                    System.out.println("Oh boy, something broke!");
                    e.printStackTrace();
                    throw e;
                }
            }
        };

        return super.submit(wrappedTask);
    }
};

Of course, this method only works if you're the one building the ExecutorService in the first place. Furthermore, remember to override all three submit() variants.

这篇关于从Java ExecutorService捕获线程异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆