簡體   English   中英

布爾屬性Getter和Setter鎖定

[英]Boolean Property Getter and Setter Locking

你有沒有理由在這個布爾屬性的getter和setter周圍創建鎖?

  private _lockObject = new object();
  private bool _myFlag;
  public bool MyFlag
  {
    get
    {
      lock (_lockObject)
      {
        return _myFlag;
      }
    }
    set
    {
      lock (_lockObject)
      {
        _myFlag = value;
      }
    }
  }

好吧,你不一定需要 - 但如果你想要一個線程肯定讀取另一個線程寫的值,你需要鎖或一個volatile變量。

我個人放棄了試圖理解volatile的確切含義。 我盡量避免編寫自己的無鎖代碼,而是依靠真正了解內存模型的專家。

編輯:作為這可能導致的問題的一個例子,請考慮以下代碼:

using System;
using System.Threading;

public class Test
{
    private static bool stop = false;

    private bool Stop
    {
        get { return stop; }
        set { stop = value; }
    }

    private static void Main()
    {
        Thread t = new Thread(DoWork);
        t.Start();
        Thread.Sleep(1000); // Let it get started
        Console.WriteLine("Setting stop flag");
        Stop = true;
        Console.WriteLine("Set");
        t.Join();
    }

    private static void DoWork()
    {
        Console.WriteLine("Tight looping...");
        while (!Stop)
        {
        }
        Console.WriteLine("Done.");
    }
}

該計划可能會也可能不會終止。 我看到兩者都發生了。 不能保證“讀取”線程實際上會從主存儲器中讀取 - 它可以將stop的初始值放入寄存器中,並且永遠保持使用它。 實際上,我已經看到了這種情況。 它不會發生在我當前的機器上,但它可能會在我的下一台機器上發生。

根據問題中的代碼將鎖置於屬性getter / setter中將使此代碼正確並且其行為可預測。

有關這方面的更多信息,請參閱Eric Lippert撰寫的這篇博客文章

. bool的讀寫是

但是,名稱“flag”表示在發生某些情況之前,單獨的線程將進行讀/寫。 為避免由於優化而導致的意外行為,您應該考慮將volatile關鍵字添加到bool聲明中。

沒有理由在那里鎖定。

在你的設計中采取鎖定可能是合適的,但是這是正確的粒度是非常值得懷疑的。

您需要使設計成為線程安全的,而不是單個屬性(甚至整個對象)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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