更新地图/设置并自动检查尺寸

时间:2018-09-05 13:09:05

标签: java multithreading concurrency thread-safety hashset

我有以下方法:

private static HashSet<Integer> ids = new HashSet<>();  
public static void someMethod(SomeObject o) {  
  // some code  

 ids.add(o.getId());   
 if(ids.size() > 10) {  
   // do something  
 }  
 else {  
  // do something else  
 }  
}  

使此方法线程安全的一种简单方法是添加关键字synchronized
我想知道是否已经有一些更合适的方法在地图/集合中添加项目并自动检查大小

1 个答案:

答案 0 :(得分:1)

这样的事情不存在,正如评论中所说的,ConcurrentHashMap甚至都无法帮助您。

请务必小心,不要落入此处的“检查即行动”反模式陷阱。例如,不要这样做:

 Set<Integer> syncIds = Collections.synchronizedSet(ids);
 syncIds.add(o.getId())  
 if(ids.size() > 10) {....}

作为单独的操作,这些确实是线程安全的,但作为复合操作,则不是。

请记住,由于您在锁下更新了HashSet,因此在读取时必须在相同的锁下完成 ,这就是之前发生的事情有效。因此,如果您公开一个方法:

public Set<Integer> getIds(){
    return ids;
}

为使此方法正常运行,并且您不会感到意外,该方法也需要同步。