次のような状況があります。
シングルトン クラス、複数のスレッドがアクセスしているコーディネーターと呼びましょう。このクラスの役割は、特定のエンティティ (EntityObject) をスレッドセーフな方法で「初期化」することです。EntityObject を初期化しようとしている 5 つのスレッドがあるとします。1 つのスレッドのみが EntityObject の初期化を許可され、他の 4 つのスレッドは初期化が完了するまで待機する必要があります。EntityObjects は、その名前によって一意です。
これを説明するコードを次に示します。
public class EntityObject
{
public EntityObject()
{
IsInitialized = false;
Name = string.Empty;
}
public bool IsInitialized { get; set; }
public string Name { get; set; }
}
public class InitializeArguments
{
public EntityObject Entity { get; set; }
}
public class Coordinator
{
public void initialize(InitializeArguments args)
{
if (!args.Entity.IsInitialized)
{
//initializeCode goes here
//only one thread is allowed to initialize an EntityObject with a certain Name
//the other threads have to wait until initialization is done
args.Entity.IsInitialized = true;
}
}
}
class Program
{
static void Main(string[] args)
{
List<Task> allTask = new List<Task>();
Coordinator coordinator = new Coordinator();
EntityObject entity1 = new EntityObject() { IsInitialized = false, Name = "entity1" };
EntityObject entity2 = new EntityObject() { IsInitialized = false, Name = "entity2" };
EntityObject entity3 = new EntityObject() { IsInitialized = false, Name = "entity3" };
for (int i = 0; i < 4; i++)
{
var task = Task.Factory.StartNew(() =>
{
InitializeArguments initArg = new InitializeArguments() { Entity = entity1 };
coordinator.initialize(initArg);
});
allTask.Add(task);
}
for (int i = 0; i < 4; i++)
{
var task = Task.Factory.StartNew(() =>
{
InitializeArguments initArg = new InitializeArguments() { Entity = entity2 };
coordinator.initialize(initArg);
});
allTask.Add(task);
}
for (int i = 0; i < 4; i++)
{
var task = Task.Factory.StartNew(() =>
{
InitializeArguments initArg = new InitializeArguments() { Entity = entity3 };
coordinator.initialize(initArg);
});
allTask.Add(task);
}
Task.WaitAll(allTask.ToArray());
Console.ReadLine();
}
}
この場合、entity1、entity2、entity3 は 1 回だけ初期化する必要があります。
これを実現するために a を使用することを考えていましたが、 Dictionary<string, ManualResetEventSlim>
機能させることができません。