我设计的是有一些静态辞典的Web服务(WCF)(即维护服务器和连接的客户端的一些州)。该服务是在单一实例模式和多个并发性,如下所示。
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class CalculatorService : ICalculatorConcurrency
{
...
}
有读取和写入该静态变量的各种操作。我有一个一流水平的锁定对象,我尽量避免锁是使用对象,只要任何操作试图访问特定的静态变量的方式。
难道我正确处理并发性,如下图所示?可以有访问服务的客户端的各种情况下,即
示例代码是这样的:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)]
public class CalculatorService : ICalculatorConcurrency
{
private static int clientId;
private static object lockObject = new object();
private static Dictionary<int, Number> numberList = new Dictionary<int, Number>();
public static Number ReadNumber(int n)
{
Number info;
lock (lockObject)
{
if (!numberList.TryGetValue(n, out info))
...
}
}
public static bool Modify(Number number)
{
lock (lockObject)
{
...
}
}
public bool Clear()
{
lock (lockObject)
{
numberList.Clear();
...
}
}
}
是我的代码线程安全的?或者,而且我是不是做正确吗?
由于您使用的只是一个资源(即lockObject
)死锁是不可能的。为了得到你需要有至少两个资源死锁。
是我的代码线程安全的?
如果您正在使用Dictionary<,>
,以避免任何并发问题与字典的每一次互动应该lock(lockObject){}
像你一样被包裹。所以,你的代码是线程安全的。
我在做正确吗?
你是做正确,但如果您使用的是.Net 4
或最新的你有线程安全的ConcurrentDictionary<TKey,TValue>
更方便的选择。它是为像你的情况而设计的专用。所不同的是,你可以约lock
块算了。当通过字典一个呼叫者迭代和第二呼叫者改变字典它不会抛出异常。 ConcurrentDictionary<TKey,TValue>
实现IDictionary<TKey,TValue>
并且此外,提供了方便的方法,如TryAdd
,TryUpdate
等。
所以,你一定要使用ConcurrentDictionary
,如果它是可能的,因为它使代码更干净。