私はC#で簡単なキャッシュロジックをテストしています。以下はマルチスレッドでローカル変数をロックする必要がありますか?
public class CacheManager
{
static List<string> _list = new List<string>();
static readonly object _syncobject = new object();
public static void ReloadList()
{
List<string> list = new List<string>();
Random r = new Random();
var count = r.Next(10);
for (int i = 0; i < count; i++)
{
list.Add("list" + i);
}
//lock (_syncobject)
{
_list = list;
}
}
public static IEnumerable<string> GetList()
{
//lock (_syncobject)
{
return _list;
}
}
}
のCacheManagerを消費する多くのスレッドを生成クラスがされています:ここに私のCacheManagerクラスがある
class Program
{
static void Main(string[] args)
{
//threads for re-loading the list
for (int i = 0; i < 3; i++)
{
Thread reloadThread = new Thread(ReloadList);
reloadThread.Start();
}
//threads for getting the list
for (int i = 0; i < 10; i++)
{
Thread tget = new Thread(PrintList);
tget.Start();
}
//threads for getting the list and storing in local variable then use it
for (int i = 0; i < 10; i++)
{
Thread tget = new Thread(PrintListWithLocalVariable);
tget.Start();
}
Console.ReadKey();
}
private static void ReloadList()
{
do
{
Console.WriteLine("Reloading **********");
CacheManager.ReloadList();
} while (true);
}
private static void PrintList()
{
do
{
foreach (var item in CacheManager.GetList())
{
if (item == null)
throw new Exception("i == null");
Console.WriteLine(item);
}
} while (true);
}
private static void PrintListWithLocalVariable()
{
do
{
var list = CacheManager.GetList();
foreach (var listitem in list)
{
var i = list.FirstOrDefault(x => x.Equals(listitem));
if (i == null)
throw new Exception("i == null");
Console.WriteLine("Printing with Local variable:" + listitem);
}
} while (true);
}
}
私の理解で私たちはCacheManagerの中_list変数をロックする必要がありますが、私たちのようには見えませんでしたそれが必要です。上記のテストを1時間ほど実行しましたが、何のエラーもありませんでした。 ReloadThreadはリスト項目、リストをループしている他のスレッドの乱数をリロードしていますが、私は問題があると思っていました。誰も私のプログラムが問題なく実行されている理由を説明することはできますか?
ありがとうございました。
独自のキャッシュを作成する必要はありますか? https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx。また、ConcurrentCollectionを使用してみてください。 https://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx –
FYI、 '_list'は「ローカル」変数ではありません。 – crashmstr
説明は:あなたが幸運を得たからです。あなたはこれを次の100回実行すると幸運かもしれません。しかし、それはあなたが正しく働くために必要とするとすぐに不快な場所であなたを回して刺すでしょう。 – nvoigt