【问题标题】:A small query about locks in c# threading关于c#线程中锁的一个小查询
【发布时间】:2012-06-01 14:13:16
【问题描述】:

我看到很多使用静态只读对象的锁定,在下面给出的代码中这条语句的意义是什么?我知道锁被应用在一个对象上,这只是一个使锁工作的对象,它只是一个黑客,因为我在这里不需要任何对象,而只是创建一个对象以使锁定起作用?

另外,我不只是说 object obj1= new object() 我使用只读和静态,我猜是因为提高了性能,但只读和静态如何帮助提高性能?

static readonly object locker = new object();

代码如下:

class ThreadSafe 
{
  static bool done;
  static readonly object locker = new object();

  static void Main()
  {
    new Thread (Go).Start();
    Go();
  }

  static void Go()
  {
    lock (locker)
    {
      if (!done) { Console.WriteLine ("Done"); done = true; }
    }
  }
}

【问题讨论】:

标签: c# thread-safety


【解决方案1】:

使用单独的私有对象而不是已经存在的全局可见对象进行锁定是recommended practice,因为其他代码的锁定决定干扰您的私有锁定方案的风险较低(这类问题极难记录反对和诊断;所以最好让他们不可能)。

如果它服务于静态类,或者如果您的意图是应用程序范围的锁定,则该 locker 对象需要是静态的;如果它仅用于锁定单个对象实例,则它必须是实例对象,从而允许并发处理同一服务类或类层次结构的其他对象。

在这种特殊情况下,显式只读不会对性能产生直接影响,但在大多数其他情况下(主要是通过防止重新加载)会产生直接影响,因此将所有只读对象标记为此类是一个有用的习惯。

【讨论】:

    【解决方案2】:

    拥有一个唯一目的是提供锁的对象可以稍微简化一些事情。为了防止外部代码弄乱你的锁并给你带来各种各样的痛苦,你真的很想要一个对你唯一可见的锁。最简单的方法是创建一个对象。 (如果你有另一个没有其他人可以访问的对象,你可以想象使用它......但是将锁与其他所有东西分开往往会使东西在概念上更简单。)

    至于为什么它是静态的...与其说是性能问题,不如说是正确性问题。为了锁定静态方法或同步对静态资源的访问,您需要一个属于该类的对象,而不是一个实例。否则,每个实例都将锁定自己的锁而不是共享一个——除非只有一个实例,否则这将毫无用处,即使在那时也不正确。对于非静态方法,您不会使用static,除非出于某种原因您正在访问静态属性或类似的东西。如果您确实使用了它,并且不需要在实例之间同步访问,那么您最终会不必要地锁定并减慢速度。

    【讨论】:

      猜你喜欢
      • 2017-07-06
      • 2015-07-20
      • 2013-08-13
      • 1970-01-01
      • 2018-05-31
      • 2023-03-24
      • 1970-01-01
      • 2012-10-13
      相关资源
      最近更新 更多