携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
-
execute()方法对应的异常也可以被捕获
运行类代码如下:
@Slf4j public class ExecuteCatchExceptionRun { public static void main(String[] args) { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,3,10, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>()); threadPoolExecutor.setThreadFactory(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler () { @Override public void uncaughtException(Thread t, Throwable e) { log.info("执行execute()方法通过使用自定义ThreadFactory也能捕获异常"); e.printStackTrace(); } }); return thread; } }); threadPoolExecutor.execute(new Runnable() { @Override public void run() { Integer.valueOf("A"); } }); } }运行结果如下:
16:49:42.898 [Thread-0] INFO com.ozx.concurrentprogram.executor.controller.ExecuteCatchExceptionRun - 执行execute()方法通过使用自定义ThreadFactory也能捕获异常
java.lang.NumberFormatException: For input string: "A" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.valueOf(Integer.java:766) at com.ozx.concurrentprogram.executor.controller.ExecuteCatchExceptionRunWorker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
从运行结果看出线程池执行execute()方法原来不能捕获异常,直接输出堆栈信息,但是可以通过自定义ThreadFactory的方式进行捕获异常。
Future的缺点
接口Future的实现类是FutureTask.java,而且在使用线程池时,默认情况下也是使用FutureTask.java类作为接口Future的实现类,简单说就是如果使用Future与Callable的使用情况下,使用Future接口也就是在使用FutureTask.java实现类。
Callable接口与Runnable接口的最大优点如下:
-
Callable接口可以通过Future取得返回值。
但是Future接口调用get()方法取得处理的返回值时是阻塞的,简单就是如果调用Future对象的get()方法时,任务暂时未执行完成,那么调用get()方法时会一直阻塞到这任务完成时为止。如果是这样的情况,前面的任务一旦耗时比较久,则后来的任务调用get()方法也会呈现阻塞状态,就是排队进行等待,大大影响运行效率,就是Future的缺点,主线程无法保证获得的是最先完成任务的返回值。