C#中锁定(或进入/退出)的最佳实践

时间:2011-05-04 04:24:52

标签: c# multithreading locking

我有一个测量仪器对象:

public class Instrument
{
  public double Measure() 
  { 
    return 0; 
  }
}

我有一个需要做一些测量的设备:

public class Device
{
  public Instrument MeasuringInstrument { get; set; }
  public void DoMeasuring()
  {
    var result = this.MeasuringInstrument.Measure();
  }
}

测量仪器一次只能在一台设备上运行,但许多设备可能使用同一台仪器。我是线程新手,根据我的理解,以下两种解决方案都有警告。

public class Instrument
{
  public double Measure() 
  { 
    lock(this)
    {
      return 0; 
    }
  }
}

public class Device
{
  public Instrument MeasuringInstrument { get; set; }
  public void DoMeasuring()
  {
    lock(this.MeasurementInstrument)
    {
      var result = this.MeasuringInstrument.Measure();
    }
  }
}

我已经读过最好锁定私有对象,但我不知道如何做到这一点,同时仍允许在Device上获取/设置MeasuringInstrument。有什么建议吗?

非常感谢,

2 个答案:

答案 0 :(得分:5)

如果多个instrument使用了devices,则最佳做法是在lock课程中设置instrument。所以第一种解决方案效果更好。

但最好创建一个新的锁对象并在instrument类中使用它。

public class Instrument
{
  Object lockKey = new Object();
  public double Measure() 
  { 
    lock(lockKey)
    {
      return 0; 
    }
  }
}

答案 1 :(得分:3)

通常的模式是创建自己的私有object,仅用于锁定明显选择可能暴露在类外的情况,例如:

public class Instrument
{
    private object thisLock = new object();

    public double Measure() 
    { 
        lock(this.thisLock)
        {
            return 0; 
        }
    }
}

public class Device
{
    public Instrument MeasuringInstrument { get; set; }
    private object measuringInstrumentLock = new object();

    public void DoMeasuring()
    {
        lock(this.measuringInstrumentLock)
        {
            var result = this.MeasuringInstrument.Measure();
        }
    }
}

另外,我怀疑你只需要这两个锁中的一个(DoMeasuring中的一个或Measure中的一个),尽管这取决于丢失的位。