我正在写性能关键代码,因此想要最大限度地减少对lock(){ ... }
的调用。
关键部分是一个字典:C#条件锁
private static readonly Dictionary<string, System.Messaging.MessageQueue> _messageQueues;
读取,并在同一时间从/到字典添加时,则有可能是损坏的数据。这就是为什么我不想同时允许这两个操作。
SOLUTION 1
lock (_lock) {
_messageQueues.Add(queueName, result);
}
和另一种方法:
lock(_lock){
if (_messageQueues.TryGetValue(queueName, out result)) {
return result;
}
}
但我不喜欢这样的解决方案,因为现在只有一个线程可以同时读取。
如果正在进行书写,我想允许多个读者或者没有读者。
解决方案2
添加一个布尔字段:
private static volatile bool _currentlyModifying;
写入字典这样的:
try {
_currentlyModifying = true;
lock (_lock) {
_messageQueues.Add(queueName, result);
}
}
finally {
_currentlyModifying = false;
}
和阅读这样的:
if (_currentlyModifying) {
lock (_lock) {
if (_messageQueues.TryGetValue(queueName, out result)) {
return result;
}
}
} else {
//Here is the new problem
if (_messageQueues.TryGetValue(queueName, out result)) {
return result;
}
}
问题
这将工作得很好,但有一个竞争条件:
一个线程可以开始写后,另一个线程已开始阅读。
有没有办法解决这个问题?
为什么不使用'ConcurrentDictionary'而不是? –
查看.Net的ConcurrentDictionary类可能会有所帮助。只是不知道它如何处理哪些线程可以读取,但我认为他们有一个很好的解决方案。 –
解决方案2(用于* general *用法)的另一个问题是,是否有多个写入者尝试访问该锁。如果他们都同时到达'lock()',他们中的一个将进入,进行更改,释放锁(第二个写入者现在可以获得锁),* unsets *'_currentlyModifying',而第二个写入者仍然在锁里面。 –