シナリオ
リソースをダウンロードしたい。リソースを複数回ダウンロードしたくありません。スレッドaがリソースをダウンロードする場合はキャッシュ1
する必要があり、スレッドbが同時に1
リソースをダウンロードしようとする場合は、待機してキャッシュされたリソースを使用する必要があります。1
スレッドcがリソースをダウンロードしたい場合、スレッドaとb2
の影響を受けてはなりません。
試み
以下のシナリオを実装しようとしました。
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleApplication1
{
class ConditionalThreadLockingProgram
{
private static readonly object _lockObject = new object();
private static readonly Dictionary<int, string> Locks =
new Dictionary<int, string>();
private static readonly Dictionary<int, string> Resources =
new Dictionary<int, string>();
public static string GetLock(int resourceId)
{
lock (_lockObject)
{
if (Locks.ContainsKey(resourceId))
{
return Locks[resourceId];
}
return Locks[resourceId] = string.Format(
"Lock #{0}",
resourceId
);
}
}
public static void FetchResource(object resourceIdObject)
{
var resourceId = (int)resourceIdObject;
var currentLock = GetLock(resourceId);
lock (currentLock)
{
if (Resources.ContainsKey(resourceId))
{
Console.WriteLine(
"Thread {0} got cached: {1}",
Thread.CurrentThread.Name,
Resources[resourceId]
);
return;
}
Thread.Sleep(2000);
Console.WriteLine(
"Thread {0} downloaded: {1}",
Thread.CurrentThread.Name,
Resources[resourceId] = string.Format(
"Resource #{0}",
resourceId
)
);
}
}
static void Main(string[] args)
{
new Thread(FetchResource) { Name = "a" }.Start(1);
new Thread(FetchResource) { Name = "b" }.Start(1);
new Thread(FetchResource) { Name = "c" }.Start(2);
Console.ReadLine();
}
}
}
質問
それは機能しますか?問題はありますか?