使用多线程非常容易引起错误,对于复杂的业务逻辑来说,定位错误并非易事。
以上代码使用线程池创建5个线程任务,分别计算2个数的商,理论上应该输出5个结果,分别是100除以i的值,但实际结果是只输出了4个。问题出在了100/0出现了异常,但是程序并没有打印出任何日志信息,线程池可能会吞掉异常堆栈,这样对于排查问题就非常困难。
解决方式是将exe.submit()改成exe.execute()或者使用Future改造一下,
Future ft = exe.submit(new DivTask(100, i));
ft.get();
这两种方式都可以将部分异常堆栈信息打出,但是这种方式只能知道异常在哪里抛出的,具体任务提交位置等信息却不可见。使用ThreadPoolExecutor扩展线程池,在调度任务前保存要提交任务线程的堆栈信息。
--参考文献《实战Java高并发程序设计》