[英]Is super.clone() of Cloneable a thread safe method?
如果我有一個類Foo
public class Foo implements Serializable, Cloneable {
public Foo() {}
protected String s;
protected int n;
public Foo clone() {
return (Foo) super.clone();
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public String getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
}
它在MyClass
使用,並且將處理程序傳遞給兩個線程A
和B
,如果線程A同時嘗試克隆處理程序,而線程B嘗試更改處理程序的公共變量,會發生什么情況呢?
例如
Foo Class
s = "Hello"
n = "42"
此類傳遞給同時運行的A
和B
A
想要克隆Foo Class
並且在1 µs之后B
想要將n更改為43
。
克隆結果將為s = "Hello" and n = "42" || n = "43"
s = "Hello" and n = "42" || n = "43"
?
更簡單: super.clone()
是線程安全的,還是我必須使用lock
或synchronized
? 如果我必須使用lock
或synchronized
,那是使用它們的最佳方法?
您稍微誤用了“線程安全”一詞。 這並不意味着“同步”,這顯然是您使用它的方式。 同步量無法防止實現錯誤破壞線程安全。 例如,您編寫的任何在不持有任何鎖的情況下對對象進行變異的代碼都將明顯違反該對象的線程安全性,並且像Object.clone
這樣的庫方法對此無能為力。
最終,線程安全性始終由實現者掌握, Object.clone()
不會為您帶來任何困難:它所做的只是讀取當前對象的狀態並將其復制到新對象。 它不會發布該新對象。
沒有將clone
專門描述為線程安全的,這意味着不是。 如果一個線程正在克隆對象,而另一個線程正在更改對象,則克隆可能會以不一致的狀態結束。
您可以在clone
函數中獲取一個鎖,但是更好的方法是在調用clone
的代碼中獲取它。
不,如果兩個線程試圖在相同的Foo實例上執行此方法,則它不是線程安全的。
您應該使用該實例創建一個互斥鎖。例如,將執行此克隆方法的代碼放置在synced(fooInstance)塊中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.