我有一个并发HashMap实例,一些线程向其中添加条目。这些值是整数。
同时,其他线程希望检索映射中所有值的总和。我希望这些线程看到一致的值。但是,不必一定总是让他们看到最新的值。
以下代码线程安全吗?
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MyClass {
private Map<Integer, Integer> values = new ConcurrentHashMap<>();
public void addValue(Integer key, int value){
values.put(key, value);
}
public long sumOfValues(){
return values
.values()
.stream()
.mapToInt(Integer::intValue)
.sum();
}
}
求和运算是否将根据一组一致的值进行计算?
当求和运算发生时,是否会阻止对put()的调用?
当然,我可以自己同步访问,甚至可以拆分读写锁,以允许并发读取访问和同步写访问,但是我很好奇在将并发HashMap用作集合实现时是否必要。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Java中,ConcurrentHashMap
是线程安全的,它允许多个线程同时进行读和写操作而不需要外部同步。这意味着在你的代码中,addValue
方法和sumOfValues
方法可以被多个线程并发调用而不会导致数据不一致的问题。
关于你的问题:
求和运算是否将根据一组一致的值进行计算?
在sumOfValues
方法中,虽然你是在遍历映射的值来求和,但由于ConcurrentHashMap
的迭代器具有弱一致性(而不是即时一致性),这意味着它可能反映最近完成的put操作之前的状态。因此,求和可能不是基于最新的一组值,但会基于某个时间点的一致性快照。这符合你的要求,即不必总是看到最新的值,但要保证看到的是一个一致的视图。
当求和运算发生时,是否会阻止对put()的调用?
不会。ConcurrentHashMap
的设计允许读取操作和写入操作并发执行,也就是说,在求和过程中,其他线程仍然可以调用addValue
方法添加条目。它通过内部的分段锁机制来实现这一点,确保了高并发下的性能和线程安全性,而不会因为读取操作阻塞写入操作或反之。
综上所述,你的代码片段在使用ConcurrentHashMap
时是线程安全的,并且满足你所描述的需求:允许并发添加条目,同时求和操作能看到一个一致的值集合,尽管这个集合可能不是实时最新的。由于ConcurrentHashMap
本身的特性,额外的同步措施(如读写锁)在这里通常是不必要的,除非有更严格的并发控制需求。