[英]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.