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-数据同步线程”。
此程序应用在同步数据库时,有些特定的情况导致线程停止,但数据库数据还没有同步完,可以再重新打开线程,再同步完剩下的数据。