锁定在整个应用程序中使用的对象的线程实例是一种好做法吗?

本文关键字:一种 实例 应用程序 线程 对象 锁定 | 更新日期: 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",否则会产生不必要的争用。这就像两个不重叠的十字路口有一个红灯。

相关文章: