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()); } } }
运行代码,结果:
线程变了,也就数据丢失了,
再来看一下不丢失数据的代码
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,比较简单。感兴趣的可以自己瞅瞅源码就知道啦。
再来看一下运行后的结果:
即使是线程改变 了,值也是可以取到的,至此我也就做了个简单的测试。
http://www.spring4all.com/article/948文章写得比较好,感兴趣的可以自己去看看。