前言
最近在給熔斷器組件增加一個降級策略(hystrix好像沒有這個配置),我們提供了如下幾種策略:
1、默認策略
2、返回常量值
3、拋出指定異常
4、執行一段groovy腳本
當然了,這些配置都是可以在平臺上配置,并立即生效的。
目前返回常量值的實現如下:
今天發現,如果每次都返回同一個對象,而且這個邏輯對業務來說是黑盒(業務不知道每次拿到的對象是同一個),如果對這個對象進行了操作,那肯定會影響到其它的請求,為了避免背鍋,我們需要每次返回一個新的對象,第一反應是通過clone是否可行(因為每次json的序列化也會損耗性能),但是jdk自帶的clone方法只是淺克隆,如果對象中包含了另一個復雜對象,clone出來的對象還是存在被修改的風險。
詳細介紹:
大家可以看下面一個例子:
1
2
3
4
5
6
|
class master { string name; public master(string name) { this .name = name; } } |
初始化一個master類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class dog implements cloneable { string name; int age; master master; public dog(string name, int age, master master) { this .name = name; this .age = age; this .master = master; } @override protected object clone() throws clonenotsupportedexception { return super .clone(); } @override public string tostring() { return "{name:" + name + ", age: " + age + ", master: " + master.name + "}" ; } } |
再初始化一條狗
1
2
3
4
5
6
7
8
|
public static void main(string[] args) throws exception { master master = new master( "zj0" ); dog dog1 = new dog( "旺財" , 1 , master); dog dog2 = (dog)dog1.clone(); dog1.name = "比利" ; dog1.master.name = "zj1" ; system.out.println(dog2); } |
最后運行一下,結果如下:
1
|
{name:旺財, age: 1 , master: zj1} |
dog1是原始狗,dog2是克隆出來的,但是我修改dog1的master的name時,克隆的master也跟著變化了,這顯然不行。
雖然一直都知道object的clone方法是淺克隆,也一直沒繼續探索一下,今天碰到了就順手看下jvm的實現,好像很簡單,在jvm.cpp文件中,搜索"jvm_clone"
以前一直沒用過clone這個方法,通過源碼發現在運行的時候會檢查類是否實現cloneable接口,編譯的時候不檢查,想啥呢?
根據對象或者數據的大小,從堆中開辟一塊同等大小的內存,然后把原始對象的數據都復制到新的內存地址,對于基本類型,可以把原始值復制過來,但是對于內部對象來說,其保存的只是一個地址,復制時也是對地址的復制,最終還是指向同一個對象,所以就造成了上述的問題。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://www.jianshu.com/p/309f80f33190