托管线程是否可能与自己有竞争条件?
本文关键字:自己 竞争 条件 线程 是否 | 更新日期: 2023-09-27 18:04:17
因此,为了为程序运行的每个线程提供单独的上下文,我设置了一个上下文-线程映射类,如下所示
public class ContextMap : IContextMap
{
private static IContextMap _contextMap;
private Dictionary<int, IArbContext2> ContextDict;
private static string DbName;
private ContextMap()
{
if (string.IsNullOrWhiteSpace(DbName))
throw new InvalidOperationException("Setup must be called before accessing ContextMap");
ContextDict = new Dictionary<int, IArbContext2>();
}
protected internal static void Setup(IContextMap map)
{
_contextMap = map;
}
public static void Setup(string dbName)
{
DbName = dbName;
}
public static IContextMap GetInstance()
{
return _contextMap ?? (_contextMap = new ContextMap());
}
public IArbContext2 GetOrCreateContext()
{
var threadId = Thread.CurrentThread.ManagedThreadId;
if(!ContextDict.ContainsKey(threadId))
ContextDict.Add(threadId,new ArbContext(DbName));
return ContextDict[threadId];
}
public void DestroyContext()
{
if (ContextDict.ContainsKey(Thread.CurrentThread.ManagedThreadId))
ContextDict.Remove(Thread.CurrentThread.ManagedThreadId);
}
不知何故,代码(很少但仍然发生)在GetOrCreateContext方法中抛出keynotfound异常。一个线程是否有可能被转移到一个单独的动作(例如,监督线程强制它做另一个动作,导致线程在检查字典是否有键后调用DestroyContext,但在它返回它之前),然后在它离开的地方恢复。我从来没有特别这样做过,但是我不明白为什么会抛出这个错误。
谢谢。
问题是Dictionary
不是线程安全的。当多个线程试图访问它时,可能会出现意外行为,即使它们都使用唯一的键,因为创建或删除键/值对不是原子操作。
最简单的修复方法是使用ConcurrentDictionary
来代替ContextDict
回答你的字面问题,而不是试图解决你的问题。(@BenAaronsom已经这么做了)
No:当某些计算的结果取决于两个或多个线程访问同一变量的顺序时,就会出现"竞争条件"。如果赛跑中只有一个线程在运行,那么无论运行多少次,同一个线程总是会获胜。如果单线程程序给出了一个不确定的答案,那么无论问题是什么,它都不是竞争条件。