锁定在整个应用程序中使用的对象的线程实例是一种好做法吗?
本文关键字:一种 实例 应用程序 线程 对象 锁定 | 更新日期: 2023-09-27 18:16:19
我所见过的每个锁的例子都使用私有对象来锁定特定的代码块,线程同步(c#)给出了相同的例子,但也说"严格地说,提供的对象仅用于唯一地标识多个线程之间共享的资源,因此它可以是任意的类实例。"实际上,这个对象通常表示线程同步所必需的资源。"(强调我的。)在我的示例中,在我的代码中,只有一个"MyClass"实例,它在自己的线程上运行,并且对它的引用被传递给各种其他类。
是否可以锁定MyClass引用,然后调用Ready(),或者我应该在MyClass中放置一个私有对象()并锁定它,如lockkedready()方法所示?提前感谢您的回答。
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
}
}
}
}
从功能上讲,一个对象并不比另一个对象性能好,除非其他锁定关注点共享使用该对象。
在c#中,锁在实际的域对象上而不是锁的代理对象上是很常见的。使用成员对象也很常见,一个常见的遗留示例是早期System.Collections中的SyncRoot对象。两种方法都可以,只要使用引用类型。然而,使用内部代理锁对象的参数是封装之一。如果您的类的用户决定使用您的类作为锁,它消除了外部干扰的可能性。使用内部锁对象可以保护锁免受外部干扰,因此有人可能会认为锁是应该隐藏的实现细节。
重要的是要确保它是正确和适当的。确保以适当的粒度进行锁定。(例如,使用静态锁对象可能不是非单例的最佳方法,甚至可能不是大多数单例的最佳方法)。在类具有多个互斥线程操作的情况下,您不希望锁定"this",否则会产生不必要的争用。这就像两个不重叠的十字路口有一个红灯。