[英]Thread-safe lazy initialization
我已經閱讀了有關線程安全的延遲初始化的內容,並且我在String類中查看了hashCode方法的實現。 顯然這個方法是線程安全的,我為另一個類(不可變)創建了我自己的版本。
private int hashcode;
@Override
public int hashCode() {
int h = hashcode;
if (h == 0 && array.length > 0) {
hashcode = (h = Arrays.hashCode(array));
}
return h;
}
我的問題是:它真的是線程安全的嗎? 我不明白為什么。 我沒有看到什么阻止線程進入該方法,而另一個仍然在里面,但也許它錯了。
您看到的代碼可能效率低下。 可能發生的是多個線程同時進入hashCode()
函數並且它們都計算哈希碼而不是只計算哈希碼中的一個而其他線程等待結果。
因為String
是不可變的,所以這不是問題。 如果對象是可變的,則需要在其hashCode()
函數中進行同步(因為在hashCode()
內部可以更改對象的狀態。
正如@JB Nizet指出的那樣,主要問題是你可能有一個非空數組,其哈希值恰好為0
。 你需要能夠區分“Hash is really 0”和“Hash is unknown”。 您可以使用可為空的Integer
:
private final AtomicReference<Integer> hashcode = new AtomicReference<>();
@Override
public int hashCode() {
Integer h = hashcode.get();
if (h != null) return h;
int computedHash = Arrays.hashCode(array);
hashcode.compareAndSet(null, computedHash);
return computedHash;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.