【并发编程】- 线程池使用execute、submit方法对异常处理

68 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情

上一篇文章- 【并发编程】- 线程池使用自定义拒绝策略

  1. execute()出现异常后直接输出堆栈信息,而submit()方法可以捕获异常继续

    运行类代码如下:

    public class ExecuteExceptionRun {
        public static void main(String[] args) {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
            threadPoolExecutor.execute(
                    new Runnable() {
                        @Override
                        public void run() {
                            Integer.parseInt("A");
                        }
                    }
            );
        }
    }
    

    运行结果如下:

    Exception in thread "pool-1-thread-1" 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.parseInt(Integer.java:615) at com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun1.run(ExecuteExceptionRun.java:20)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutor1.run(ExecuteExceptionRun.java:20) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

    从运行结果看出execute()方法直接抛出异常而不能捕获到异常。

    修改运行类代码如下:

    @Slf4j
    public class ExecuteExceptionRun {
        public static void main(String[] args) {
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    
            Future<String> future = threadPoolExecutor.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Integer.parseInt("A");
                    return String.valueOf(System.currentTimeMillis());
                }
            });
            try {
                log.info(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                log.error("Callable能捕获到异常");
                e.printStackTrace();
            }
    
            threadPoolExecutor.execute(
                    new Runnable() {
                        @Override
                        public void run() {
                            Integer.parseInt("A");
                        }
                    }
            );
        }
    }
    

    运行结果如下:

    16:25:05.473 [main] ERROR com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun - Callable能捕获到异常

    java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: "A" at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:192) at com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun.main(ExecuteExceptionRun.java:26)

    Caused by: 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.parseInt(Integer.java:615) at com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun1.call(ExecuteExceptionRun.java:21)atcom.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun1.call(ExecuteExceptionRun.java:21) at com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun1.call(ExecuteExceptionRun.java:18) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)atjava.lang.Thread.run(Thread.java:748)Exceptioninthread"pool1thread2"java.lang.NumberFormatException:Forinputstring:"A"atjava.lang.NumberFormatException.forInputString(NumberFormatException.java:65)atjava.lang.Integer.parseInt(Integer.java:580)atjava.lang.Integer.parseInt(Integer.java:615)atcom.ozx.concurrentprogram.executor.controller.ExecuteExceptionRunWorker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Exception in thread "pool-1-thread-2" 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.parseInt(Integer.java:615) at com.ozx.concurrentprogram.executor.controller.ExecuteExceptionRun2.run(ExecuteExceptionRun.java:38) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

    从运行结果看出线程池执行submit()方法出现异常,能被捕获到相关异常。