[英]Is it Thread-safe on this operating on ConcurrentHashMap?
private final ConcurrentHashMap<Float, VoteItem> datum = new ConcurrentHashMap<>();
public void vote(float graduation) {
datum.putIfAbsent(graduation, new VoteItem(graduation, new AtomicInteger(0)));
datum.get(graduation).getNum().incrementAndGet();
}
方法表決是否完全線程安全? VoteItem.getNum()返回AtomicInteger嗎? 還是有更好的方法來實現?
如果VoteItem#getNum()
是線程安全的,例如返回final屬性, 並且沒有在並行線程中執行刪除操作,則您的代碼也是線程安全的,因為putIfAbsent()
沒有機會覆蓋現有條目,因此沒有機會讓get()
返回被覆蓋的條目。
但是,還有一種更通用的方法是使用putIfAbsent()
結果來實現它,如果給定鍵存在該值,則返回現有值:
public void vote(float graduation) {
VoteItem i = datum.putIfAbsent(graduation, new VoteItem(graduation, new AtomicInteger(1)));
if (i != null)
i.getNum().incrementAndGet();
}
這也處理了同時刪除的可能性。 與您的代碼相反,可以在putIfAbsent()
和get()
之間執行並發刪除從而導致NPE,在這種情況下不會發生這種情況。
並考慮使用computeIfAbsent()
代替putIfAbsent()
,以避免不必要的VoteItem
創建:
public void vote(float graduation) {
datum.computeIfAbsent(graduation, g -> new VoteItem(g, new AtomicInteger(0)))
.getNum()
.incrementAndGet();
}
可以在result上調用getNum()
,因為與putIfAbsent()
,如果在插入之前不存在值的情況下返回null,則它僅返回計算值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.