1

私は次のような状況にあります:

多くのオブジェクトを格納するには、リストなどが必要です。

それらはすべて、リスト自体を含む 1 つのクラスによって生成されます。

現在、他のスレッドに少なくとも 1 つ (おそらくそれ以上) のクラスがあり、常にリストの最初のオブジェクトから開始し、次のオブジェクトを定期的に (20ms-100ms) 取得します。

リストは時間とともに増えています。最後に、最大 300k オブジェクトが存在する可能性があります。(このオブジェクトの 1 つには、最大 50 の int またはそのような sth を含めることができます)

独自のイテレータ実装を持つ ConcurrentLinkedQueue は正しい方法ですか? 削除オプションを拒否するには独自のイテレータが必要ですか?

4

2 に答える 2

1

リストが大きくなるにつれてリストを反復処理する1人のライターと複数のリーダーがいる場合は、はい、ConcurrentLinkedQueue. これは、キューでの複数の同時操作用に設計されています。

Javadocsは、リストへの変更を繰り返すことについて明確に警告しているため、使用できません。Collections.synchronizedList

ユーザーは、返されたリストを反復処理するときに手動で同期することが不可欠です。

ConcurrentLinkedQueue明らかに、キューが巨大になる (300k アイテム)ため、イテレータを使用する方法が適しています。Queueプログラムがエントリなどを探すためにキュー全体を実行するメソッドには注意してください。

考慮すべきもう 1 つのオプションは、ConcurrentSkipListMapJava 6+ で利用できるものです。これは log2 ルックアップ マップですが、順序付けされたエントリも含まれているため、反復はキューと同じです。これにより、コレクションに対してマップ操作とキュー操作を同時に実行できます。スキップリスト++。

編集:

削除オプションを拒否するには独自のイテレータが必要ですか?

削除を許可しないようにイテレータをオーバーライドする必要があるかどうかを尋ねている場合は、そうします。全体を拡張してQueue、独自のカスタム委任イテレータを返し、ブロックすることを検討することもできQueue.remove(...)ます。

于 2012-11-09T19:49:47.137 に答える
0

ライターは 1 つだけで、リーダーは多数あるため、 の使用を検討してCopyOnWriteArrayListください。ドキュメントから:

ArrayList基になる配列の新しいコピーを作成することによって、すべての変更操作 (追加、設定など) が実装されるのスレッドセーフなバリアント。

これは通常コストがかかりすぎますが、トラバーサル操作がミューテーションよりもはるかに多い場合、代替手段よりも効率的である可能性があり、トラバーサルを同期できない、または同期したくないが、同時スレッド間の干渉を排除する必要がある場合に役立ちます。「スナップショット」スタイルの反復子メソッドは、反復子が作成された時点での配列の状態への参照を使用します。この配列はイテレータの有効期間中に変更されることはないため、干渉は不可能であり、イテレータは をスローしないことが保証されています ConcurrentModificationException

編集:グレイが指摘しているように、挿入の数が非常に多いため、このソリューションは法外なものになっています-私は彼のソリューションに行きます。

于 2012-11-09T19:55:03.677 に答える