美文网首页
UnSuspendThread 一个假的不中断的线程

UnSuspendThread 一个假的不中断的线程

作者: Mr_UU | 来源:发表于2019-05-28 17:11 被阅读0次

    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 一个假的不中断的线程

          本文链接:https://www.haomeiwen.com/subject/iwodtctx.html