ThreadLocal传值丢失问题

参考:http://www.spring4all.com/article/948

在Spring Cloud中我们用Hystrix来实现断路器,Zuul中默认是用信号量(Hystrix默认是线程)来进行隔离的,我们可以通过配置使用线程方式隔离。

先来看一下丢失时的代码

public class Main {
    static ThreadLocal<Object> objectThreadLocal = new ThreadLocal<>();
//    static InheritableThreadLocal<Object> objectThreadLocal = new InheritableThreadLocal<>();
    public static void main(String[] args) {
        new Thread(()->{
            objectThreadLocal.set("zj");
            System.out.println("Main:" + Thread.currentThread().getName());
            System.out.println("Main:" + Main.objectThreadLocal.get());
            new Server().run();
        }).start();
    }
    static class Server{
        protected void run(){
            System.out.println("==========================");
            System.out.println("Service:" + Thread.currentThread().getName());
            System.out.println("Service:" + Main.objectThreadLocal.get());
            new Thread(()->{
                new Dao().run();
            }).start();
        }
    }
    static class Dao{
        public void run(){
            System.out.println("==========================");
            System.out.println("Dao:" + Thread.currentThread().getName());
            System.out.println("Dao:" + Main.objectThreadLocal.get());
        }
    }
}

运行代码,结果:

ThreadLocal传值丢失问题

线程变了,也就数据丢失了,

再来看一下不丢失数据的代码

public class Main {
//    static ThreadLocal<Object> objectThreadLocal = new ThreadLocal<>();
    static InheritableThreadLocal<Object> objectThreadLocal = new InheritableThreadLocal<>();
    public static void main(String[] args) {
        new Thread(()->{
            objectThreadLocal.set("zj");
            System.out.println("Main:" + Thread.currentThread().getName());
            System.out.println("Main:" + Main.objectThreadLocal.get());
            new Server().run();
        }).start();
    }
    static class Server{
        protected void run(){
            System.out.println("==========================");
            System.out.println("Service:" + Thread.currentThread().getName());
            System.out.println("Service:" + Main.objectThreadLocal.get());
            new Thread(()->{
                new Dao().run();
            }).start();
        }
    }
    static class Dao{
        public void run(){
            System.out.println("==========================");
            System.out.println("Dao:" + Thread.currentThread().getName());
            System.out.println("Dao:" + Main.objectThreadLocal.get());
        }
    }
}

上述代码也就是吧ThreadLocal替换为InheritableThreadLocal,这里不解释InheritableThreadLocal,比较简单。感兴趣的可以自己瞅瞅源码就知道啦。

再来看一下运行后的结果:

ThreadLocal传值丢失问题

即使是线程改变 了,值也是可以取到的,至此我也就做了个简单的测试。

http://www.spring4all.com/article/948文章写得比较好,感兴趣的可以自己去看看。