锁定整个应用程序中正在使用的对象的线程化实例是一种好习惯吗?

时间:2014-08-05 04:01:37

标签: c# multithreading

我见过的每个锁定示例都使用私有对象来锁定特定的代码块,而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
                }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

从功能上讲,无关紧要,一个对象的性能不如另一个,除非其他锁定问题共同使用该对象。

使用C#,锁定实际的域对象而不是锁定的代理对象并不罕见。查看使用的成员对象也很常见,常见的遗留示例是早期System.Collections上的SyncRoot对象。无论哪种方式都有效,只要您使用引用类型。

但是,使用内部代理锁对象的参数是封装之一。如果您班级的用户决定将您的班级用作锁,则可以消除外部干扰的可能性。使用内部锁定对象可以保护锁免受外部干扰,因此可以认为锁定是应该隐藏的实现细节。

重要的是要确保它是正确和适当的。确保以适当的粒度完成锁定。 (例如,使用静态锁定对象可能不是非单例的最佳方法,甚至可能不是大多数单例)。如果您的类具有多个互斥的线程操作,则您不希望锁定“this”或者您有不必要的争用。这就像为一个非重叠交叉点设置一个红灯。