【发布时间】:2012-09-24 21:56:10
【问题描述】:
我想知道在属性中正确使用锁。我正在编写一个多线程服务器应用程序,其中吞吐量非常重要。如果我有这样声明的属性:
private DataPoint a;
private object aLock = new object();
最保守的锁似乎如下(称之为方法1)。但是,在这种情况下,在第一次调用之后的每次调用,都会产生锁开销:
public DataPoint A
{
get
{
lock (aLock)
{
if (a == null)
{
a = new DataPoint();
}
return a;
}
}
}
或者,我应该将锁移动到设置“a”的行(称为方法 2)。在这种情况下,“a”可能会被设置多次(这没关系),但一旦设置,就没有锁的开销。
public DataPoint A
{
get
{
if (a == null)
{
lock(aLock)
{
a = new DataPoint();
}
}
return a;
}
}
锁定对属性的并发访问的推荐方法是什么?是方法一、方法二还是以上都不是?
谢谢。
【问题讨论】:
-
第二个例子中的
lock完全没有意义(没有双关语),但是你是否应该锁定(而不是仅仅拥有一个合理的初始化值)是一个不同的问题。 -
为什么不在类构造函数中初始化你的DataPoint?
-
第二个例子可能是一个有效的场景,这取决于 DataPoint 的构造函数中发生了什么。出于说明目的,我不应该使用“new DataPoint()”,而是使用类似 DataPoint.Create("A")...
-
您正在开发服务器并且您有锁?祝你好运。
-
第二种情况确实有效。如果它已经被初始化,你可能不想锁定它。但是,在 lock(aLock) 之后,您应该(再次)检查 a 是否为空,否则如果在 a 未初始化时执行了对 getter 的两个并发调用,您可能最终会初始化多次。
标签: c# .net multithreading concurrency clr