UnSuspendThread 一个假的不中断的线程

UnSuspendThread 一个假的不中断的线程

一般Thread内while(true),循环内使用try{}cache{}:

        new Thread(() -> {
            while(true){
                try {
                    System.out.println("线程运行中...");
                    int a = 1/0;
                }catch (Exception e){
                    printExceptionInfo(Thread.currentThread());
                }
            }
        }).start();

一般异常都可以通过try{}cache(Exception e){}来捕获,然而。。。

当你这么写的时候,有时候程序并不是按照预想的步骤执行的,总有那么几次线程诡异的就结束了。。。

比如:

        new Thread(() -> {
            while(true){
                try {
                    System.out.println("线程运行中...");
                    throw new Error("捕获不了吧");
                }catch (Exception e){
                    printExceptionInfo(Thread.currentThread());
                }
            }
        }).start();

线程启动级结束。当然你也可以直接捕捉Exception和Error,就像:

catch (Error | Exception e) {
    printExceptionInfo(Thread.currentThread());
}

怎么看都有点怪异

那么,有没有个优雅的方式实现 不中断线程?

java.lang.Thread类里有个接口“UncaughtExceptionHandler”了解下?

既然是个接口,那么使用之前就需要先实现它,比如说这样:

    public static class UncaughtExceptionHandlerDemo implements Thread.UncaughtExceptionHandler{
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            printExceptionInfo(t);
            e.printStackTrace();
            System.out.println("重新启动线程...");
            t = createUnSuspendThread();
            pause(1000);
            setDefaultExceptionHandler(t);
            t.start();
        }

        public static void setDefaultExceptionHandler(Thread t){
            System.out.println("设置默认异常处理器,do something...");
            // 此处可用单例
            t.setUncaughtExceptionHandler(new UncaughtExceptionHandlerDemo());
            System.out.println("设置默认异常处理器。。。done");
        }
    }

如果一个Thread对象调用了setUncaughtExceptionHandler方法,并且如果恰好调用方法时传入的参数 是 UncaughtExceptionHandlerDemo对象

那么,当这个Thread对象发生异常时(未捕获异常),就会触发UncaughtExceptionHandlerDemo对象的uncaughtException方法

比如说这样:

    public static void main(String[] args) {
        Thread thread = createUnSuspendThread();
        UncaughtExceptionHandlerDemo.setDefaultExceptionHandler(thread);
        thread.start();
    }

    public static Thread createUnSuspendThread() {
        return new Thread(() -> {
            System.out.println("抛出异常前。。。");
//           int a = 1/0;
            throw new Error();
        }, "测试线程");
    }

在执行main方法的时候,理论上 应该先去找一个叫“createUnSuspendThread”的静态方法,该方法会返回一个Thread对象,然后给这个Thread对象添加一个DefaultexceptionHandler即UncaughtExceptionHandlerDemo对象

然后 这个thread开始运行,运行到"throw new Error()"时,不出意外就应该结束了,

如果你在用调试模式的话,此时程序应该跳到了 UncaughtExceptionHandlerDemo 类的 uncaughtException 方法里,

然后打印信息blablabla,然后又tm创建个Thread对象,然后又tm设置了 UncaughtExceptionHandlerDemo

然后又开始运行 Thread#start 方法了,然后。。。

然后 一个一直报错一直自动重新开启线程的 线程,就这么诞生了。。。

为了凑字数,完整代码给你:

/**
 * @Author: wang_z
 * @Date: 2019/5/28 14:08
 * @Description:
 */
public class UncaughtExceptionHandlerTest {

    public static void main(String[] args) {
        Thread thread = createUnSuspendThread();
        UncaughtExceptionHandlerDemo.setDefaultExceptionHandler(thread);
        thread.start();
    }

    public static Thread createUnSuspendThread() {
        return new Thread(() -> {
            System.out.println("抛出异常前。。。");
//            int a = 1/0;
            throw new Error();
        }, "测试线程");
    }

    public static void printExceptionInfo(Thread t){
        System.out.println(String.format("线程%s[%d]异常结束,异常信息:", t.getName(), t.getId()));
    }
    public static void pause(long milles){
        try {
            Thread.currentThread().sleep(milles);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static class UncaughtExceptionHandlerDemo implements Thread.UncaughtExceptionHandler{
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            printExceptionInfo(t);
            e.printStackTrace();
            System.out.println("重新启动线程...");
            t = createUnSuspendThread();
            pause(1000);
            setDefaultExceptionHandler(t);
            t.start();
        }

        public static void setDefaultExceptionHandler(Thread t){
            System.out.println("设置默认异常处理器,do something...");
            t.setUncaughtExceptionHandler(new UncaughtExceptionHandlerDemo());
            System.out.println("设置默认异常处理器。。。done");
        }
    }
}

你可能感兴趣的:(UnSuspendThread 一个假的不中断的线程)