線程運行過程當中發生的異常,沒法經過try catch方式,在外層進行捕獲,例如java
try { new Thread(new Runnable() { @Override public void run() { int i = 1 / 0; } }).start(); } catch (Exception e) { System.out.println("error"); }
執行上面的代碼,你會發現,error永遠不會打印在你的控制檯或是log中,緣由爲什麼,沒去深究,不過我想大概是由於線程有本身獨立的棧區多線程
try { Thread thread = new Thread(new Runnable() { @Override public void run() { int i = 1 / 0; } }); thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("uncaughtException"); } }); thread.start(); } catch (Exception e) { System.out.println("error"); }
private static ThreadPoolExecutor executorPool = new ThreadPoolExecutor(4, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1), new SimpleThreadFactory("executor"), new CustomRejectedExecutionHandler() ) { @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); if (t == null && r instanceof Future<?>) { try { Object result = ((Future<?>) r).get(); } catch (CancellationException ce) { t = ce; } catch (ExecutionException ee) { t = ee.getCause(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // ignore/reset } } if (t != null) { System.out.println("t is :" + t); t.printStackTrace(); } } };
這樣就能夠在異常發生時,能夠打印出異常信息,而不是被吃掉ide
咱們在sumbit任務到ThreadPool時,自動爲咱們包裝成了FutureTask,而FutureTask對象在執行時,是會把異常吃掉,直到咱們get FutureTask的執行結果時纔會把異常拋出。相關的代碼以下: 工具