• 线程池异常堆栈的坑


    
    import java.util.concurrent.*;
    
    public class DivTask implements Runnable{
        int a,b;
    
        public DivTask(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
        @Override
        public void run() {
            double re = a/b;
            System.out.println(re);
        }
        public static void main(String[] args) throws InterruptedException, ExecutionException {
    //        ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 0L, TimeUnit.SECONDS
    //                , new SynchronousQueue<>());
            TraceThreadPoolExecutor executor = new TraceThreadPoolExecutor(0, Integer.MAX_VALUE, 0L, TimeUnit.SECONDS
                    , new SynchronousQueue<>());  //扩展TraceThreadPoolExecutor
            for (int i = 0; i < 5; i++) {
                // executor.submit(new DivTask(100,i));
                //改进方式一:
                //Future re = executor.submit(new DivTask(100, i));
                //re.get();
                //改进方式二:
                executor.execute(new DivTask(100,i));
            }
            //100.0
            //25.0
            //33.0
            //50.0
            //其中100/0的异常结果没打印
            //线程池很有可能"吃掉程序抛出的异常
    
            //改进方式一:
            //Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
            //	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
            //	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
            //。。。
    
            //改进方式二:
            //Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
            //	at com.Test.DivTask.run(DivTask.java:15)
            //	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)
            //100.0
            //33.0
            //25.0
            //50.0
    
            //扩展TraceThreadPoolExecutor
            //java.lang.Exception: Client stack trace
            //	at com.Test.TraceThreadPoolExecutor.clientTrace(TraceThreadPoolExecutor.java:20)
            //	at com.Test.TraceThreadPoolExecutor.execute(TraceThreadPoolExecutor.java:12)
            //	at com.Test.DivTask.main(DivTask.java:29)
            //Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero
            //	at com.Test.DivTask.run(DivTask.java:15)
            //	at com.Test.TraceThreadPoolExecutor.lambda$wrap$0(TraceThreadPoolExecutor.java:25)
            //	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)
            //100.0
            //25.0
            //33.0
            //50.0
        }
    }
    
    
    import java.util.concurrent.*;
    
    /**
     * 扩展TraceThreadPoolExecutor,让它在调度任务前先保存一下提交任务线程的堆栈信息
     */
    public 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 task) {
            super.execute(wrap(task,clientTrace(),Thread.currentThread().getName()));
        }
    
        @Override
        public Future<?> submit(Runnable task) {
            return super.submit(wrap(task,clientTrace(),Thread.currentThread().getName()));
        }
        private Exception clientTrace(){
            return new Exception("Client stack trace");
        }
        private Runnable wrap(final Runnable task,final Exception clientTrace,String clientThreadName){
            return () -> {
                try {
                    task.run();
                } catch (Exception e) {
                    clientTrace.printStackTrace();
                    throw e;
                }
            };
        }
    }
    
  • 相关阅读:
    JDK源码之Thread 类分析
    java中符号类型和无符号类型的问题分析
    国内高速Maven仓库
    Idea Live Templates代码模板
    正则表达式
    java内存泄漏
    MySQL查看 InnoDB表中每个索引的高度
    ThreadLocalMap里Entry为何声明为WeakReference?
    Java JDBC中,MySQL字段类型到JAVA类型的转换
    MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现
  • 原文地址:https://www.cnblogs.com/fly-book/p/11464655.html
Copyright © 2020-2023  润新知