[英]Locks in properties
我想知道屬性中鎖的正確使用。 我正在編寫一個多線程服務器應用程序,其中吞吐量非常重要。 如果我有一個這樣聲明的屬性:
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;
}
}
鎖定並發訪問屬性的推薦方法是什么? 是方法1,方法2還是以上都不是?
謝謝。
在.NET 4中,您具有System.Lazy<T>
類型,可以為您解決以下問題:
class MyClass
{
private readonly Lazy<DataPoint> lazy =
new Lazy<Singleton>(() => new DataPoint());
public DataPoint Instance { get { return lazy.Value; } }
}
在鎖定示例中,您正在這樣做以初始化值。 假設條件為空意味着需要初始化該值,則應在獲取鎖之前和之后對其進行檢查:
if(a == null)
{
lock(aLock)
{
if(a == null)
a = new DataPoint();
}
}
這樣做的原因是,當線程正在等待鎖時,一旦獲得鎖,線程將要執行的工作可能已經由其他線程完成了。 因此,當線程獲取鎖時,它應該檢查以查看是否仍需要完成工作。
您應該在鎖定之前檢查null。 如果為null,則鎖定,然后再次檢查null。 如果仍然為空,請啟動您的DataPoint並將其首先分配給一個臨時變量。 完成后,將其分配給您的成員並返回。
private DataPoint _dataPoint;
public DataPoint A
{
get
{
if(_dataPoint != null)
return _dataPoint;
lock (aLock)
{
if (_dataPoint == null)
{
var dataPoint = new DataPoint();
// do more stuff with dataPoint
_dataPoint = dataPoint;
}
return _dataPoint;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.