C# のスレッドセーフリスト
-
C# の
ConcurrentBagクラスのスレッドセーフリスト -
C# の
ConcurrentQueueクラスを使用したスレッドセーフリスト -
C# の
SynchronizedCollectionクラスを使用したスレッドセーフリスト
このチュートリアルでは、C# でスレッドセーフリストを作成する方法を紹介します。
C# の ConcurrentBag クラスのスレッドセーフリスト
ConcurrentBag クラスは、C# でスレッドセーフな順序付けられていないデータのコレクションを作成するために使用されます。ConcurrentBag クラスは C# の List と非常によく似ており、C# のスレッドセーフリストとして使用できます。ConcurrentBag クラスを使用するには、プロジェクトに System.Collections.Concurrent 名前空間をインポートする必要があります。複数のスレッドが ConcurrentBag オブジェクトに同時にアクセスできますが、ConcurrentBag オブジェクト内のコンテンツは同期的にのみ変更できます。並行操作のために複数のスレッドで使用可能であり、偶発的なデータ損失から安全になります。次のコード例は、C# で ConcurrentBag クラスを使用してスレッドセーフリストを作成する方法を示しています。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace thread_safe_list {
class Program {
static void Main(string[] args) {
ConcurrentBag<int> numbers = new ConcurrentBag<int>();
numbers.Add(0);
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);
numbers.Add(4);
numbers.Add(5);
Console.WriteLine("ConcurrentBag");
foreach (var number in numbers) {
Console.WriteLine(number);
}
List<int> nums = new List<int>();
nums.Add(0);
nums.Add(1);
nums.Add(2);
nums.Add(3);
nums.Add(4);
nums.Add(5);
Console.WriteLine("List");
foreach (var number in nums) {
Console.WriteLine(number);
}
}
}
}
出力:
ConcurrentBag
5
4
3
2
1
0
List
0
1
2
3
4
5
上記のコードでは、C# の ConcurrentBag クラスでスレッドセーフリストを作成しました。新しい要素 Add() を追加する関数は、ConcurrentBag と List の両方のデータ構造で同じです。唯一の違いは、リストが先入れ先出し法(FIFO)で機能するのに対し、ConcurrentBag は後入れ先出し法(LIFO)で機能することです。この問題は、以下のコード例で対処されています。
C# の ConcurrentQueue クラスを使用したスレッドセーフリスト
ConcurrentQueue クラスは、C# でスレッドセーフなキューデータ構造を作成するために使用されます。ConcurrentQueue は、C# のリストと同様に、先入れ先出しの原則に基づいて機能します。List オブジェクトの代わりに ConcurrentQueue オブジェクトを使用して、スレッドセーフなデータ構造を作成できます。次のサンプルコードを参照してください。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace thread_safe_list {
class Program {
static void Main(string[] args) {
Console.WriteLine("Concurrent Queue");
ConcurrentQueue<int> numbers = new ConcurrentQueue<int>();
numbers.Enqueue(0);
numbers.Enqueue(1);
numbers.Enqueue(2);
numbers.Enqueue(3);
numbers.Enqueue(4);
numbers.Enqueue(5);
foreach (var number in numbers) {
Console.WriteLine(number);
}
Console.WriteLine("List");
List<int> nums = new List<int>();
nums.Add(0);
nums.Add(1);
nums.Add(2);
nums.Add(3);
nums.Add(4);
nums.Add(5);
foreach (var number in nums) {
Console.WriteLine(number);
}
}
}
}
出力:
Concurrent Queue
0
1
2
3
4
5
List
0
1
2
3
4
5
上記のコードでは、C# の ConcurrentQueue クラスを使用してスレッドセーフなリストデータ構造を作成しました。List と ConcurrentQueue のデータ構造で使用できるメソッドには、かなりの違いがあります。たとえば、List データ構造に新しい要素を追加するメソッドは Add() です。対照的に、ConcurrentQueue データ構造に新しい要素を追加する方法は Enqueue() であり、これは C# の従来の Queue データ構造とまったく同じです。ConcurrentQueue データ構造のこの欠点は、次の例で対処されます。
C# の SynchronizedCollection クラスを使用したスレッドセーフリスト
SynchronizedCollection クラスは、C# で指定されたタイプのオブジェクトのスレッドセーフなコレクションを作成するために使用されます。SynchronizedCollection データ構造は、C# の List データ構造と非常によく似ています。どちらのデータ構造も、先入れ先出しの原則に基づいて機能します。SynchronizedCollection と List データ構造の両方に新しい要素を追加する関数は Add() です。次の例を参照してください。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
namespace thread_safe_list {
class Program {
static void Main(string[] args) {
Console.WriteLine("Synchronized Collection");
SynchronizedCollection<int> numbers = new SynchronizedCollection<int>();
numbers.Add(0);
numbers.Add(1);
numbers.Add(2);
numbers.Add(3);
numbers.Add(4);
numbers.Add(5);
foreach (var number in numbers) {
Console.WriteLine(number);
}
Console.WriteLine("List");
List<int> nums = new List<int>();
nums.Add(0);
nums.Add(1);
nums.Add(2);
nums.Add(3);
nums.Add(4);
nums.Add(5);
foreach (var number in nums) {
Console.WriteLine(number);
}
}
}
}
出力:
Synchronized Collection
0
1
2
3
4
5
List
0
1
2
3
4
5
上記のコードでは、C# の SynchronizedCollection クラスを使用してスレッドセーフリストを作成しました。これまでのところ、このアプローチは、同じ FIFO の原則に従い、同じメソッドを使用しているため、C# でリストデータ構造の機能を実装するための他の 2つのアプローチの中で最適です。
Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.
LinkedIn