如果
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()
和
获取()
因此导致NPE,这里不可能发生这种情况。
并考虑使用
computeIfAbsent()
而不是
putIfAbsent()
为了避免不必要的
VoteItem
创作:
public void vote(float graduation) {
datum.computeIfAbsent(graduation, g -> new VoteItem(g, new AtomicInteger(0)))
.getNum()
.incrementAndGet();
}
使命感
getNum()
结果是可能的,因为与
putIfAbsent()
,如果值在插入之前不存在,则返回null,它只返回计算值。