2

この投稿の概要:注文されたアイテムのセットがあり、その注文は時間の経過とともに変更される可能性があります。複数のスレッドからこのセットを反復処理できる必要があります。各スレッドは、アイテムの順序も更新する必要がある場合があります。

たとえば、複数のスレッドはString、任意の並べ替えられた順序でキーにアクセスする必要があります。これらの文字列は、自然順序ではなく、変更される可能性のあるいくつかの値(したがって、カスタムComparator)によって並べ替えられます。私の最初の実装は、を使用しTreeSetて同期することでした。キーのいずれかを並べ替える必要がある場合、スレッドはマップからキーを削除し、比較値を更新して、キーを再挿入します。これを実装するために、キーはネイティブですStringが、コンパレータは値にアクセスできます。これは、キーの順序が時間の経過とともに変化する可能性がある奇妙な配置ですが、変更されたキーは常に削除され、変更されると再挿入されるため、機能しているように見えます。String( sが別のオブジェクトにラップされている場合にも機能すると思います。)

私は最近、基本的にスレッドセーフなソートされたセット(またはマップ)であるConcurrentSkipListSet/ConcurrentSkipListMap実装に気付きました。データ構造全体をロックすることなく、キーを反復処理できるようになりました。ただし、上記で行った操作のように、キーをアトミックに削除して別のキーに置き換える方法はありますか?これにより、他の反復スレッドがアイテムを見逃さず、synchronizeブロックを使用する必要がなくなります。

誰かがこのタイプの操作のためのより良いデータ構造を提案することができれば、私もすべての耳です!

4

1 に答える 1

3

上記で行っていた操作のように、キーをアトミックに削除して別のキーに置き換えるためにそれらを使用できる方法はありますか?

短い答えはノーです。削除して再挿入する必要がある場合、私が知っているコレクションでこれを行うアトミックな方法はありません。

とはいえ、スキップ リストから項目を削除するに項目を再挿入することも 1 つの可能性です。これにより重複が発生しますが、エントリが欠落している場合よりも処理が簡単になる場合があります。オブジェクトを変更した後に再挿入すると、別の方法でソートされます。これは、オブジェクトも等しくないことを前提としています。しかし、リストを処理している他のスレッドが重複を処理できない場合、あなたは SOL だと思います。

于 2013-03-19T18:22:00.977 に答える