Scenario
I want to download resources. I don't want a resource to be downloaded more that once. If thread a downloads resource 1
it should be cached, and thread b should wait and use the cached resource 1
if it attempts to download resource 1
at the same time. If thread c wants to download resource 2
, it should not be influenced by thread a and b.
Attempt
I have tried to implement the scenario below:
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();
}
}
}
Question
Does it work? Any issues?