キーと値の両方でエントリをソートできるが、値をアトミックに更新/インクリメントできるコレクションを作成しようとしています。ConcurrentHashMap を使用したキーでのみ注文できるため、ConcurrentSkipListSet を使用してみましたが、ConcurrentHashMap のように putifabsent と replace(key,oldvalue,newvalue) をサポートしていないため、値を原子的に更新/増加する方法がよくわかりませんコレクションを設定します。
ConcurrentSkipListSetに使用していた私のコンパレーターはこちら
最初の文字列、次に値、2 番目の文字列の順に並べる必要があります。
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);
}
};
残念ながら、2 つの文字列を組み合わせて単一のキーを形成することはできません。これは、「最初の文字列、2 番目の文字列、任意の値に一致」などのクエリを実行し、結果をコンパレーターで並べ替える必要があるためです。設定。ただし、タプルを更新する必要がある場合は、最初に古い値を取得する必要があります
OldValue = Set.ceiling(new Fun.Tuple3<>(String,String,Integer.MinValue))
次に、要素をセットから削除し、整数を 1 増やして、再度セットに追加します。問題は、Set.ceiling、remomve、および add 呼び出しの間で、値が別のスレッドによって追加/削除/変更された可能性があることです。
>のような方法なしで
AtomicIncrement(Tuple3 tuple3){
oldValue = Set.ceiling(tuple3)
while(true){
if(set.replace(oldValue,newValue)) return;
}
}
値を安全に更新する方法がわかりません。