我见过的每个锁定示例都使用私有对象来锁定特定的代码块,而Thread Synchronization (C#)给出了同样的示例,但也说“严格来说,提供的对象仅用于唯一标识多个线程之间共享的资源,因此它可以是任意类实例。但实际上,此对象通常表示需要进行线程同步的资源。“(强调我的。)在我的示例中,在我的代码中,只有一个“MyClass”实例,它在自己的线程上运行,并且对它的引用被传递给其他各个类。
是否可以锁定MyClass引用然后调用Ready(),或者我应该在MyClass中放置一个私有对象()并锁定它,如LockedReady()方法所示?提前感谢您的回答。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var uc = new UserClass();
uc.DoThings();
}
}
public class MyClass
{
public bool Ready()
{
//determine if the class is ready to perform its function
//assumes that the instance of MyClass is locked,
//as shown in UserClass.DoThings
}
private object _readyLock = new object();
public bool LockedReady()
{
lock (_readyLock)
{
//determine if the class is ready to perform its function
//no assumption made that the object is locked, as
//shown in AnotherClass.DoAnotherThing()
}
}
}
public class UserClass
{
private MyClass _myc;
public UserClass()
{
var t = new Thread(SetupMyClass);
t.Start();
}
private void SetupMyClass()
{
_myc = new MyClass();
}
public void DoThings()
{
lock(_myc)
{
if (_myc.Ready())
{
//Do things
}
}
}
public void DoOtherThings()
{
var ac = new AnotherClass(_myc);
ac.DoAnotherThing();
}
}
public class AnotherClass
{
private MyClass _myc;
public AnotherClass(MyClass myClass)
{
_myc = myClass;
}
public void DoAnotherThing()
{
if (_myc.LockedReady())
{
//do another thing
}
}
}
}
答案 0 :(得分:3)
从功能上讲,无关紧要,一个对象的性能不如另一个,除非其他锁定问题共同使用该对象。
使用C#,锁定实际的域对象而不是锁定的代理对象并不罕见。查看使用的成员对象也很常见,常见的遗留示例是早期System.Collections上的SyncRoot对象。无论哪种方式都有效,只要您使用引用类型。
但是,使用内部代理锁对象的参数是封装之一。如果您班级的用户决定将您的班级用作锁,则可以消除外部干扰的可能性。使用内部锁定对象可以保护锁免受外部干扰,因此可以认为锁定是应该隐藏的实现细节。
重要的是要确保它是正确和适当的。确保以适当的粒度完成锁定。 (例如,使用静态锁定对象可能不是非单例的最佳方法,甚至可能不是大多数单例)。如果您的类具有多个互斥的线程操作,则您不希望锁定“this”或者您有不必要的争用。这就像为一个非重叠交叉点设置一个红灯。