参考: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,比较简单。感兴趣的可以自己瞅瞅源码就知道啦。
再来看一下运行后的结果:
即使是线程改变 了,值也是可以取到的,至此我也就做了个简单的测试。
版本测试二
package book.test; /** * 父线程的ThreadLocal里面的值子线程获取不到演示,如果换成InheritableThreadLocal * 就成功子线程也能获取父线程传过来的ThreadLocal的值 */ public class ThreadLocalTest { public static void main(String[] args) { new ParamentThread().start(); } public static class ParamentThread extends Thread{ InheritableThreadLocal<String> paramentThreadLocal=new InheritableThreadLocal(); @Override public void run() { paramentThreadLocal.set("paramentThreadLocal"); // super.run(); System.out.println("I am is ParamentThread: "+paramentThreadLocal.get()); ChindThread chindThread=new ChindThread(paramentThreadLocal); new Thread(chindThread).start(); } } public static class ChindThread implements Runnable{ InheritableThreadLocal<String> chindThreadLocal=null; public ChindThread(InheritableThreadLocal<String> paramentThreadLocal){ this.chindThreadLocal=paramentThreadLocal; } @Override public void run() { if(chindThreadLocal==null){ System.out.println("chindThreadLocal==null"); }else{ System.out.println("chindThreadLocal!=null: "+chindThreadLocal.get()); } } } }
http://www.spring4all.com/article/948文章写得比较好,感兴趣的可以自己去看看。