您的位置:首页 > 其它

线程池定位异常抛出位置

2017-11-16 00:00 190 查看
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ExecutorTest1 {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(10));

threadPoolExecutor.submit(new Task(100, 1));
threadPoolExecutor.submit(new Task(100, 0));
threadPoolExecutor.submit(new Task(100, 2));
threadPoolExecutor.submit(new Task(100, 10));
}

static class Task implements Runnable {
private int num1;
private int num2;
public Task(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
@Override
public void run() {
System.out.println(num1 + " / " + num2 + " = " + num1 / num2);
}
}
}

在上面代码中,提交4个任务,但运行结果只有3个,因为在计算 System.out.println(num1 + " / " + num2 + " = " + num1 / num2); 中有一个被除数是0,应该抛异常,但是没有看到相应的异常。为了解决这个问题,可以把线程池方法 submit 改成 execute,这是可以看到异常堆栈信息显示是

System.out.println(num1 + " / " + num2 + " = " + num1 / num2); 这行代码出的异常。但是,看不到是哪行代码提交任务,也就是堆栈信息没有显示出 threadPoolExecutor.submit(new Task(100, 0)); 这行代码。解决这个问题,可以通过扩展线程池来达到。

static class TraceThreadPoolExecutor extends ThreadPoolExecutor {
public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
}

@Override
public void execute(Runnable command) {
super.execute(wrap(command, clientException(), Thread.currentThread().getName()));
}

@Override
public Future<?> submit(Runnable task) {
return super.submit(wrap(task, clientException(), Thread.currentThread().getName()));
}

private Exception clientException() {
return new Exception();
}

private Runnable wrap(final Runnable task, final Exception clientStack, String threadName) {
return new Runnable() {

@Override
public void run() {
try {
task.run();
} catch (Exception e) {
clientStack.printStackTrace();
throw e;
}
}
};
}
}

这时,我们在使用这个线程池来execute任务时,不仅可以看到 System.out.println(num1 + " / " + num2 + " = " + num1 / num2); 这行代码异常,同时看到 threadPoolExecutor.submit(new Task(100, 0)); 这行代码异常,这样我们就能很好的定位到提交异常任务的位置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: