解析Java线程池的异常处理机制

98 阅读2分钟

感谢:1、滑动验证页面

2、线程的异常捕获与线程池的异常捕获 execute与submit区别:线程的异常捕获与线程池的异常捕获 execute与submit区别_threadutil.execute-CSDN博客

原文:www.cnblogs.com/wscit/p/610…

3、线程吞掉异常信息 - 简书

submit的方式会吃掉异常,execute的方式会直接抛出

之后定义的时候要这样定义

对于线程池、包括线程的异常处理推荐一下方式:

  1. 直接try/catch
@Test
    public void catchThreadPoolTest() {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        try {
            Runnable runnable = () -> {
                System.out.println("-----------submit---------------");
                Object obj = null;
                System.out.println(obj.toString());
            };
            threadPool.submit(runnable).get();
        } catch (Exception e) {
            System.out.println("---------submit  Exception---------");
            e.printStackTrace();
        }
        System.out.println("-----------华丽的分割线---------------");
        threadPool.execute(() -> {
            try {
                Object obj = null;
                System.out.println(obj.toString());
            } catch (Exception e) {
                System.out.println("---------execute  Exception-----------");
                e.printStackTrace();
            }
        });
    }

2、线程直接重写整个方法:
第一段代码仅限于execute方法,因为submit的异常在线程池定义那块捕获不到,只有get的时候才会抛出,并且影响主线程的进行

@Test
    public void threadPoolTest() {
        ExecutorService threadPool = Executors.newFixedThreadPool(1, r -> {
            Thread t = new Thread(r);
            t.setUncaughtExceptionHandler(
                    (t1, e) -> System.out.println(t1 + " throws exception: " + e));
            return t;
        });
        threadPool.execute(() -> {
            System.out.println("-----------execute---------------");
            Object obj = null;
            System.out.println(obj.toString());
            System.out.println("-----------obj.toString---------------");
        });
        System.out.println("-----------afterExecue---------------");
    }
@Test
    public void catchedExecutor() {
        ExecutorService executorService = Executors.newCachedThreadPool(new MyThreadFactory());
        executorService.execute(new Task());
        executorService.shutdownNow();
        System.out.println("-----------start---------------");
    }
public class MyThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        System.out.println("Thread[" + t.getName() + "] created.");
        return t;
    }
}
public class Task implements Runnable {
    public void run() {
        System.out.println("执行任务");
        int num  = Integer.parseInt("TT");
    }
}
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler {
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕获到了线程池的异常");
    }
}
@Test
    public void rewriteUncaughtException() {
        Task task = new Task();
        Thread thread = new Thread(task);
        thread.setUncaughtExceptionHandler(new RewriteUncatchtExceptionHandler());
        thread.start();
        System.out.println("-----------start---------------");
    }
public class RewriteUncatchtExceptionHandler implements Thread.UncaughtExceptionHandler{
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println("我捕获到了线程池的异常");
    }
}
public class Task implements Runnable {
    public void run() {
        System.out.println("执行任务");
        int num  = Integer.parseInt("TT");
    }
}
@Test
    public void rewriteAfterExecute() {
        ExecutorService threadPool2 = new MyThreadPoolExecutor(1, 1, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
        threadPool2.execute(() -> {
            System.out.println("-----------execute---------------");
            Object obj = null;
            System.out.println(obj.toString());
        });
        System.out.println("-----------afterExecue---------------");
    }
public class MyThreadPoolExecutor extends ThreadPoolExecutor {
    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    protected void afterExecute(Runnable r, Throwable t) {
        if(t!=null){
            System.out.println("MyThreadPoolExecutor     "+t);
        }
    }
}
Thread t = new Thread();
       t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
 
public void uncaughtException(Thread t, Throwable e) {
LOGGER.error(t + " throws exception: " + e);
}
        });
        //如果是线程池的模式:
        ExecutorService threadPool = Executors.newFixedThreadPool(1, r -> {
 Thread t = new Thread(r);
 t.setUncaughtExceptionHandler(
  (t1, e) -> LOGGER.error(t1 + " throws exception: " + e));
 return t;
        });