參考: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文章寫得比較好,感興趣的可以自己去看看。