Java並發-UncaughtExceptionHandler捕獲線程異常信息並重新啟動線程
一、捕獲異常並重新啟用線程
1 public class Testun { 2 3 public static void main(String[] args) throws InterruptedException { 4 5 Thread thread=new TaskThread(1); 6 thread.setName("thread-數據同步線程"); 7 thread.start(); 8 } 9 } 10 11 class TaskThread extends Thread { 12 private int taskNum; 13 14 public TaskThread(int num) { 15 this.taskNum = num; 16 } 17 @Override 18 public void run() { 19 //調用捕獲異常,一定要放在要做邏輯的上面 20 Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler()); 21 //todo 22 23 int i=1/0; 24 } 25 } 26 27 class MyExceptionHandler implements UncaughtExceptionHandler { 28 @Override 29 public void uncaughtException(Thread t, Throwable e) { 30 //1.打印報錯日志 31 System.out.println("zzl異常信息: " + e.getMessage()); 32 33 //2.重新啟動線程 34 Thread[] threads = findAllThread(); //獲取所有線程 35 for (Thread thread :threads){ 36 if (thread.getName().trim().equalsIgnoreCase("thread-數據同步線程")){//校驗線程是否正在運行 37 Thread thread1=new TaskThread(1); 38 thread1.setName("thread-數據同步線程"); 39 thread1.start();//重新啟動線程 40 } 41 } 42 } 43 //查詢所有的線程 44 public Thread[] findAllThread(){ 45 ThreadGroup currentGroup =Thread.currentThread().getThreadGroup(); 46 47 while (currentGroup.getParent()!=null){ 48 // 返回此線程組的父線程組 49 currentGroup=currentGroup.getParent(); 50 } 51 //此線程組中活動線程的估計數 52 int noThreads = currentGroup.activeCount(); 53 54 Thread[] lstThreads = new Thread[noThreads]; 55 //把對此線程組中的所有活動子組的引用復制到指定數組中。 56 currentGroup.enumerate(lstThreads); 57 58 for (Thread thread : lstThreads) { 59 System.out.println("線程數量:"+noThreads+" 線程id:" + thread.getId() + " 線程名稱:" + thread.getName() + " 線程狀態:" + thread.getState()); 60 } 61 return lstThreads; 62 } 63 }
因為“thread-數據同步線程”一直處於報錯,執行失敗的情況下,所以會觸發UncaughtExceptionHandler的實現類MyExceptionHandler,在MyExceptionHandler類里面會重新打開“thread-數據同步線程”。
此程序應用在同步數據庫時,有些特定的情況導致線程停止,但數據庫數據還沒有同步完,可以再重新打開線程,再同步完剩下的數據。