这个在 ConcurrentHashMap 上的操作是线程安全的吗?
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() returns 一个原子整数?或者有没有更好的实现方式?
如果VoteItem#getNum()
是线程安全的,e。 G。 returns final 属性、和 没有在并行线程中执行删除操作,您的代码也是线程安全的,因为 putIfAbsent()
没有机会覆盖现有条目,因此 get()
到 return 条目没有机会被覆盖。
但是有更常见的方法可以使用 putIfAbsent()
的结果来实现它,如果给定键存在 return 的现有值:
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();
}
在结果上调用 getNum()
是可能的,因为与 putIfAbsent()
相比,如果值在插入之前不存在,returns 为 null,它 returns刚刚计算出的值。
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() returns 一个原子整数?或者有没有更好的实现方式?
如果VoteItem#getNum()
是线程安全的,e。 G。 returns final 属性、和 没有在并行线程中执行删除操作,您的代码也是线程安全的,因为 putIfAbsent()
没有机会覆盖现有条目,因此 get()
到 return 条目没有机会被覆盖。
但是有更常见的方法可以使用 putIfAbsent()
的结果来实现它,如果给定键存在 return 的现有值:
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();
}
在结果上调用 getNum()
是可能的,因为与 putIfAbsent()
相比,如果值在插入之前不存在,returns 为 null,它 returns刚刚计算出的值。