簡體   English   中英

鎖定屬性

[英]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; } }
} 

Jon Skeet提供

在鎖定示例中,您正在這樣做以初始化值。 假設條件為空意味着需要初始化該值,則應在獲取鎖之前之后對其進行檢查:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM