我正在尝试拥有一个集合,该集合可以按键和值对条目进行排序,但允许以原子方式更新/递增值。您只能使用 ConcurrentHashMap 对键进行排序,所以我尝试使用 ConcurrentSkipListSet 但它不支持 putifabsent 和 replace(key,oldvalue,newvalue) 就像 ConcurrentHashMap 一样,所以我不太确定如何使用设置集合。
这是我用于 ConcurrentSkipListSet 的比较器
它应该按第一个字符串排序,然后按值排序,然后按第二个字符串排序
Comparator<Fun.Tuple3<String,String,Integer>> c = new Comparator<Fun.Tuple3<String,String,Integer>>() {
@Override
public int compare(Tuple3<String, String, Integer> o1, Tuple3<String, String, Integer> o2) {
if(o1.a.compareTo(o2.a) == 0){
if(Integer.compare(o1.c,o2.c)==0){
return o1.b.compareTo(o2.b);
}
return Integer.compare(o1.c,o2.c);
}
return o1.a.compareTo(o2.a);
}
};
不幸的是,我不能将两个字符串组合在一起形成一个键,因为我需要执行诸如“匹配第一个字符串、任何第二个字符串、任何值”之类的查询,并让结果由上面的比较器排序,我可以使用放。但是,如果我需要更新一个元组,我首先需要使用
OldValue = Set.ceiling(new Fun.Tuple3<>(String,String,Integer.MinValue))
然后从集合中删除元素,然后将整数增加 1 并再次将其添加到集合中。问题是在 Set.ceiling、remove 和 add 调用之间,值可能已被另一个线程添加/删除/更改。
没有像 > 这样的方法
AtomicIncrement(Tuple3 tuple3){
oldValue = Set.ceiling(tuple3)
while(true){
if(set.replace(oldValue,newValue)) return;
}
}
我看不到如何安全地更新值。