企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
#### 线程异常处理 * 在run方法上增加异常处理 ``` new Thread(() -> { try { System.err.println(3 / 2); System.err.println(3 / 0); } catch (Exception e) { System.err.println("Catch exception===>" + e.getMessage()); } }).start(); ``` * 使用UncaughtExceptionHandler处理未捕获异常 ``` Thread thread = new Thread(() -> { System.err.println(3 / 2); System.err.println(3 / 0); }); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.err.println(Thread.currentThread().getName() + "==>" + e.getMessage()); } }); thread.start(); ``` 可以为所有的Thread设置一个默认的UncaughtExceptionHandler,通过调用Thread.setDefaultUncaughtExceptionHandler\(Thread.UncaughtExceptionHandler eh\)方法 ``` public static void main(String[] args) throws InterruptedException { Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.err.println("全局线程默认异常处理:" + t.getName() + "\n" + e.getMessage()); } }); new Thread(() -> { System.err.println(3 / 0); }).start(); new Thread(() -> { System.err.println(args[4]); }).start(); } ``` #### 线程池异常处理 ExecutorService-&gt;execute方法线程处理 ``` public class ExecuteCaught { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); Thread thread = new Thread(new Task()); thread.setUncaughtExceptionHandler(new ExceptionHandler()); exec.execute(thread); exec.shutdown(); } } output=====> 1 Exception in thread "pool-1-thread-1" java.lang.ArithmeticException: / by zero at com.exception.Task.run(NoCaughtThread.java:25) at java.lang.Thread.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) ``` 该方式并未捕获异常,正确的处理方法 ``` public class ExecuteCaught { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new ThreadPoolTask()); exec.shutdown(); } } class ThreadPoolTask implements Runnable { @Override public void run() { Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler()); System.out.println(3/2); System.out.println(3/0); System.out.println(3/1); } } ``` _注意_ 只有通过execute提交的任务,才能将它抛出的异常交给UncaughtExceptionHandler,而通过submit提交的任务,无论是抛出的未检测异常还是已检查异常,都将被认为是任务返回状态的一部分。如果一个由submit提交的任务由于抛出了异常而结束,那么这个异常将被Future.get封装在ExecutionException中重新抛出 ``` public static void main(String[] args) throws InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); exec.submit(() -> { System.err.println(3 / 0); }); exec.shutdown(); } ### 未捕获异常 ``` 正确方式: ``` public static void main(String[] args) throws InterruptedException { ExecutorService exec = Executors.newCachedThreadPool(); Future<?> future = exec.submit(() -> { System.err.println(3 / 0); }); try { Object o = future.get(); } catch (ExecutionException e) { System.err.println("捕获异常:" + e.getMessage()); } exec.shutdown(); } ``` 【知识点】 1. 如果设置了实例属性uncaughtExceptionHandler(每个线程对象独有),则调用该处理器对未捕获异常进行处理; 2. 如果没有设置未捕获异常处理器(即1中的uncaughtExceptionHandler),则将线程对象的ThreadGroup当作未捕获异常处理器,在ThreadGroup中获取所以线程对象共享的静态属性defaultUncaughtExceptionHandler来处理未捕获异常(前提是静态的set方法你调用了并且传入处理器实例\); 3. 如果两个set方法都没有调用,那么异常栈信息将被推送到System.err进行处理; 【参考资料】 https://blog.csdn.net/reliveIT/article/details/51167545