感谢:1、https://segmentfault.com/a/1190000010777336
2、线程的异常捕获与线程池的异常捕获 execute与submit区别:https://blog.csdn.net/silyvin/article/details/80025165
原文:https://www.cnblogs.com/wscit/p/6100476.html
3、https://www.jianshu.com/p/d65ea7abc480
submit的方式会吃掉异常,execute的方式会直接抛出
之后定义的时候要这样定义
对于线程池、包括线程的异常处理推荐一下方式:
-
直接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; });