线程池定位异常抛出位置
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)); 这行代码异常,这样我们就能很好的定位到提交异常任务的位置。
相关文章推荐
- iOS开发------使用Xcode编译器定位抛出异常的位置
- 确切定位c++代码中异常抛出位置的两个方法 (以VS2010调试为例)
- 确切定位c++代码中异常抛出位置的两个方法 (以VS2010调试为例)
- 线程池自定义扩展,捕获异常位置(非常有用)
- 捕获Java线程池执行任务抛出的异常
- Application-Level层级异常捕获并定位程序的异常位置
- C++中可获得抛出位置和捕获位置的异常类
- Xcode 调试器(debugger)无法定位异常抛出点 解决
- XCode的 Stack Trace,调试时抛出异常,定位到某一行代码
- 求解,多线程时,线程池中一个线程内部代码抛出异常,那么这个线程能正常结束么?
- java中定位当前异常的位置(行数)
- XCode的 Stack Trace,调试时抛出异常,定位到某一行代码
- 捕获Java线程池执行任务抛出的异常
- Locating the postion of exception 定位异常的位置
- XCode的 Stack Trace,调试时抛出异常,定位到某一行代码
- XCode的 Stack Trace,调试时抛出异常,定位到某一行代码
- Xcode准确定位异常代码位置
- 捕获Java线程池执行任务抛出的异常
- Xcode崩溃定位:异常位置Exception的断点
- 主线程捕捉线程池中线程抛出的异常