tags:

views:

62

answers:

2

I want to know if one class is inheriting from another, is it better to have the classes share a lock object that is defined at the base class or to have a lock object defined at each inheritance level.

A very simple example of a lock object on each level of the class

public class Foo {
  private object thisLock = new object();
  private int ivalue;

  public int Value { 
    get {
      lock( thisLock ) {
        return ivalue;
      }
    }
    set {
      lock( thisLock ) {
        ivalue= value;
      }
    }
  }
}

public class Foo2: Foo {
  private object thisLock2 = new object();

  public int DoubleValue { 
    get {
      lock( thisLock2 ) {
        return base.Value * 2;
      }
    }
    set {
      lock( thisLock2 ) {
        base.Value = value / 2;
      }
    }
  }
}

public class Foo6: Foo2 {
  private object thisLock6 = new object();

  public int TripleDoubleValue { 
    get {
      lock( thisLock6 ) {
        return base.DoubleValue * 3;
      }
    }
    set {
      lock( thisLock6 ) {
        base.DoubleValue = value / 3;
      }
    }
  }
}

A very simple example of a shared lock object

public class Foo {
  protected object thisLock = new object();
  private int ivalue;

  public int Value { 
    get {
      lock( thisLock ) {
        return ivalue;
      }
    }
    set {
      lock( thisLock ) {
        ivalue= value;
      }
    }
  }
}

public class Foo2: Foo {     
  public int DoubleValue { 
    get {
      lock( thisLock ) {
        return base.Value * 2;
      }
    }
    set {
      lock( thisLock ) {
        base.Value = value / 2;
      }
    }
  }
}
public class Foo6: Foo2 {     
  public int TripleDoubleValue { 
    get {
      lock( thisLock ) {
        return base.DoubleValue * 3;
      }
    }
    set {
      lock( thisLock ) {
        base.DoubleValue = value / 3;
      }
    }
  }
}

Which example is the preferred way to manage locking within an inherited class?

+3  A: 

You can find your second option quite often in the .NET Framework, using a property instead of a field though (e.g., the CommunicationObject.ThisLock Property):

public class Foo {
  private readonly object thisLock = new object();
  private int ivalue;

  protected object ThisLock {
    get {
      return thisLock;
    }
  }

  public int Value { 
    get {
      lock( ThisLock ) {
        return ivalue;
      }
    }
    set {
      lock( ThisLock ) {
        ivalue= value;
      }
    }
  }
}

and

public class Foo2: Foo {     
  public int DoubleValue { 
    get {
      lock( ThisLock ) {
        return base.Value * 2;
      }
    }
    set {
      lock( ThisLock ) {
        base.Value = value / 2;
      }
    }
  }
}
dtb
.NET Reflector finds 106 (!) occurrences of a `ThisLock` property within the assemblies I've loaded. So I guess this can be rightfully called *best-practice*. :-)
dtb
+1  A: 

How many instances of a lock object you have should equal the number of things to which you are trying to control access. If all the sub-classes are sharing the same resource, then there should be a single lock object, e.g., a field/property in the base class.

ShellShock