【发布时间】:2016-05-04 18:20:00
【问题描述】:
我正在 C# 中测试简单的缓存逻辑。这是我的 CacheManager 类:
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 的类:
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 变量,但看起来我们不需要那个。我将上述测试运行了一个小时左右,但没有出现任何错误。虽然 ReloadThread 正在重新加载随机数量的列表项,但其他线程正在循环列表中,我认为可能有问题。谁能解释一下为什么程序运行没有问题?
谢谢。
【问题讨论】:
-
您需要发明自己的缓存吗? msdn.microsoft.com/en-us/library/… 。另外,尝试使用 ConcurrentCollection。 msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx
-
仅供参考,
_list不是“本地”变量。 -
解释是:因为你走运了。在接下来的 100 次运行中,您可能会很幸运。但是当你需要它正常工作时,它会在你不舒服的地方转身咬你;
标签: c# multithreading local-variables