Java 以原子方式更新地图/设置并检查大小
我有以下方法:Java 以原子方式更新地图/设置并检查大小,java,multithreading,concurrency,thread-safety,hashset,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 e
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。
我想知道是否已经有更合适的方法在地图/集合中添加一个项目,并原子地检查大小这样的事情并不存在,正如评论中所说,即使ConcurrentHashMap也帮不了你 在这里要非常小心,不要落入检查的陷阱,而不要在这里采取反模式行动。例如,不要这样做:
Set<Integer> syncIds = Collections.synchronizedSet(ids);
syncIds.add(o.getId())
if(ids.size() > 10) {....}
要使此方法正常工作,并且您不会遇到意外情况,此方法也需要同步。除了使用synchronized关键字之外,不知道还有什么其他可能性。使用它有什么问题吗?@AnarchoEnte:我只是想知道是否有其他方法可以通过ConcurrentHashMap和类似的方式。在这篇文章之后,由于ids.size调用,您无法使用ConcurrentHashMap来实现上述代码的完整线程安全。ConcurrentHashMap不是解决方案,它将返回大小的估计值。但是如果你在这里同步整个方法,你所做的不仅仅是在地图/集合中添加一个项目并原子地检查大小,你还会做一些事情或做一些其他事情-你明白吗?@Eugene:是的,但这些部分对性能影响很小。我想知道是否有一种惯用的java方式来解决这个问题
public Set<Integer> getIds(){
return ids;
}