What is the best practice for using lock within inherited classes
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 with开发者_StackOverflow社区in an inherited class?
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;
}
}
}
}
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.
精彩评论