web-dev-qa-db-ja.com

Javaで最適な同時実行リストを選択する

スレッドプールには固定数のスレッドがあります。これらのスレッドは、共有リストから頻繁にwriteおよびreadにする必要があります。

この場合、Java.util.concurrentパッケージのどのデータ構造(リストであることが望ましい、モニターなしである必要があります)は、この場合に最適ですか?

76
象嘉道

Listの方がよい

onlyJava.util.concurrentList実装は CopyOnWriteArrayList です。 Travis Webbが言及しているように、同期リストのオプションもあります。

そうは言っても、Listである必要がありますか?コンカレントQueuesとMapsにはさらに多くのオプションがあり(SetsからMapsを作成できます)、これらの構造は多くの共有データ構造でやりたいことの種類。

キューの場合、膨大な数のオプションがあり、どのオプションを使用するかによって最適なオプションが異なります。

78
ColinD

Javaコレクションは、次のようにスレッドセーフにすることができます。

List newList = Collections.synchronizedList(oldList);

または、新しいスレッドセーフリストを作成するには:

List newList = Collections.synchronizedList(new ArrayList());

http://download.Oracle.com/javase/6/docs/api/Java/util/Collections.html#synchronizedList(Java.util.List)

52
Travis Webb

リストのサイズが固定されている場合は、 AtomicReferenceArray を使用できます。これにより、スロットに対してインデックス付き更新を実行できます。必要に応じて、リストビューを作成できます。

8
Ben Manes

ConcurrentDoublyLinkedList をご覧になるとよいでしょう。PaulMartinの「実用的なロックフリーの二重リンクリスト」に基づいてDoug Leaが作成しました。 Java.util.Listインターフェースを実装していませんが、Listで使用するほとんどのメソッドを提供します。

Javadocによると:

Deque(ダブルエンドキュー)の同時リンクリスト実装。同時挿入、削除、およびアクセス操作は、複数のスレッド間で安全に実行されます。イテレータは 弱い一貫性、イテレータの作成時以降のある時点での両端キューの状態を反映する要素を返します。彼らはConcurrentModificationExceptionを投げるnotを行い、他の操作と同時に進行するかもしれません。

6
shams

ConcurrentLinkedQueue は、ロックフリーキューを使用します(新しい CAS命令 に基づいています)。

3
eSniff

設定が十分な場合、 ConcurrentSkipListSet が使用される場合があります。 (その実装は ConcurrentSkipListMap に基づいており、これは スキップリスト を実装しています。)

予想される平均時間コストは、包含、追加、および削除操作のlog(n)です。サイズ方法は、一定時間の操作ではありません。

1
anre