C#でCopyOnWriteArrayList相当を実現する方法:SynchronizedCollectionクラスの解説
JavaにはスレッドセーフなリストとしてCopyOnWriteArrayListが用意されていますが、残念ながらC#にはこれに直接相当するクラスは存在しません。C#で同様の目的を達成したい場合は、SynchronizedCollectionクラスを使用するのが推奨されます。
SynchronizedCollectionクラスとは
SynchronizedCollectionクラスは、指定した型のオブジェクトを格納できるスレッドセーフなコレクションを提供します。複数のスレッドから同時にアクセスされても、内部で同期処理が行われるため、安全に読み書きできます。
構文
public class SynchronizedCollection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection
上記の構文において、Tはコレクションに格納されるオブジェクトの型を表します。このクラスはIList<T>やICollection<T>などの標準的なインターフェースを実装しているため、通常のコレクションと同じように扱うことができます。
SynchronizedCollectionクラスの主なプロパティ
C#のSynchronizedCollectionクラスには、以下のようなプロパティが用意されています。
| No. | プロパティ名と説明 |
|---|---|
| 1 | Count スレッドセーフなコレクション内に含まれる要素の数を取得します。 |
| 2 | Item[Int32] 指定したインデックス位置にある要素を、スレッドセーフなコレクションから取得します。 |
| 3 | Items スレッドセーフなコレクションに格納されている要素のリスト(List<T>)を取得します。 |
| 4 | SyncRoot スレッドセーフなコレクションへのアクセスを同期するために使用されるオブジェクトを取得します。 |
まとめ
C#でCopyOnWriteArrayListのようなスレッドセーフなコレクションが必要になった場合は、SynchronizedCollectionクラスが有力な選択肢となります。ただし、用途によっては.NET 4.0以降で利用可能なConcurrentNamespace(System.Collections.Concurrent)のConcurrentBagやConcurrentQueueなども検討するとよいでしょう。マルチスレッド環境での要件に応じて、最適なコレクションを選択することが重要です。
-
Javaのスレッドセーフなコレクションクラスとは?Stack・Vector・Hashtableなどを解説
スレッドセーフなクラスとは、複数のスレッドから同時に呼び出された場合でも、クラスの内部状態やメソッドの戻り値が常に正しく保たれることが保証されているクラスのことです。Javaにおいてスレッドセーフなコレクションクラスには、Stack、Vector、Properties、Hashtableなどがあります。 Stackクラス JavaのStackクラスは、LIFO(Last In First Out:後入れ先出し)の原理に基づくスタックデータ構造を実装したクラスです。push(要素の追加)、pop(要素の取り出し)、peek(先頭要素の参照)、search(検索)、empty(空判定)など、多彩な
-
Java Swingはスレッドセーフではない?その理由とEDTの正しい使い方を解説
結論から言うと、Java Swingのコンポーネントはスレッドセーフではありません。複数のスレッドから同時にSwingコンポーネントへアクセスすると、描画の不整合やデッドロックなど予期しない動作を引き起こす可能性があります。Swingがスレッドセーフではない理由最大の理由は、コンポーネントの拡張(サブクラス化)を簡単にするためです。すべてのメソッドで同期処理を行うと、開発者がオーバーライドして独自のコンポーネントを作る際に、ロックの扱いまで意識する必要が生じ、設計が複雑になってしまいます。もう一つの理由は、ロックの取得・解放や状態の復元にかかるオーバーヘッドです。全メソッドをスレッドセーフにす