我们使用哈希表在Web服务中存储会话。我想测试添加到此会话的线程安全性。我写了一个控制台应用程序,它生成了很多线程并添加到此会话中。但我既没有得到例外,也没有丢失任何数据。 我做错了什么或者这个操作不是哈希表的威胁吗?!
在这个哈希表上完成的操作非常简单:添加,删除,包含键,[](获取条目),有时更新条目的值 - 没有foreach或循环。
private const int Threads = 10000;
private const int SleepLimit = 10000;
public static void Main(string[] args)
{
try
{
Console.WriteLine("Application Started.");
Thread[] threads = new Thread[Threads];
for (int i = 0; i < threads.Length; i++)
threads[i] = CreateThread();
Console.WriteLine("All Threads Started.");
foreach (Thread t in threads)
t.Join();
Console.WriteLine("All Threads Joined.");
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred: " + ex.Message);
Console.ReadLine();
}
}
private static Thread CreateThread()
{
Thread thread = new Thread(UserFunction);
thread.Start();
return thread;
}
private static void UserFunction()
{
Thread.Sleep(_random.Next(SleepLimit));
SessionManagement.AddSession("Test");
}
public static void AddSession(string session)
{
ulong hash = NextHashValue();
while (_sessionPool.ContainsKey(hash))
{
Console.WriteLine(string.Format("Duplicate Session Key: {0}-PoolSize: {1}",
hash, _sessionPool.Count);
hash = NextHashValue();
}
_sessionPool.Add(hash, session);
if (!_sessionPool.ContainsKey(hash))
Console.WriteLine("Race problem occurred - Session Key: " + hash);
}
答案 0 :(得分:2)
我不确定为什么你会遇到这样的问题来验证对Hashtable
的并发写入是否会导致应用程序崩溃。
即使您的测试应用程序长时间安全运行,也不应该部署不能保护Hashtable
的代码免受与其他读取或写入操作同时发生的写入。
答案 1 :(得分:0)
我遇到了同样的问题。
我知道如何测试这一点的唯一方法是慢慢检查源代码或纸上所有可能的线程/锁定交互。
很久以前,我有一个应用程序,它们之间有8个线程交互,并且每周一次使用它会崩溃一次。在经历了一些崩溃之后,我开始怀疑是一个线程问题。所以我设法简化了很多锁定代码,然后我在一张纸上证明了所有可能的线程/锁定交互是安全的。这个问题消失了。