单锁对象或多锁对象,用于C#中的线程同步

时间:2018-08-15 16:10:41

标签: c# multithreading

我有一个类,其中包含一些字典对象和其他需要保护的数据。这些由多个线程(读和写)操纵。我不确定应该使用单个锁定对象来锁定全部还是每个数据应该具有不同的锁定?就我而言,慢速性能比死锁更好。

    static object object1 = new object();
    static object object2 = new object();
    private Queue<Change> changeNotifications = new Queue<Change>();
    private Dictionary<string, IConnectionClient> connectionClients1 = new Dictionary<string, IConnectionClient>(StringComparer.OrdinalIgnoreCase);
    private Dictionary<string, IConnectionClient> connectionClients2 = new Dictionary<string, IConnectionClient>(StringComparer.OrdinalIgnoreCase);

    public static void ThreadFunction1()
    {
        lock (object1)
        {
            //update connectionClients2
        }
    }

    public static void ThreadFunction2()
    {
        lock (object2)
        {
            //access changeNotifications
            //update connectionClients1
        }
    }

我的问题可以带锁使用单个锁定对象吗?

2 个答案:

答案 0 :(得分:1)

使用单个锁是一种安全的方法,但可能很慢。

如果您的资源是独立的,则一定要对每个资源使用单独的锁。

如果您需要获取多个锁,请确保始终以相同的顺序获取它们,以防止发生死锁。

答案 1 :(得分:0)

是的!尽管性能会受到打击,但这很有可能。

但是,为了保持鲁棒性和灵活性,我将创建一个线程安全的atomic包装类,围绕您需要的对象,这些对象必须可以通过多线程访问(在这种情况下为Dictionary)。这样会将锁定的封装在对象内,从而使线程安全性可以以一种更简洁的方式进行处理,并从将来的开发中抽象出来。

要这样做,一种方法可能是采用一个锁定的想法!确保对象中的所有可变字段都被锁包裹,并且您的应用程序将按需运行。一种更注重性能的方法是对每个变量使用锁。

尽管合理,但确实引起了一个问题,即为什么首先要使用多线程。通过使用一个锁,这告诉我要么保护的字段很少(在这种情况下,一个锁是有效的方法),要么对多线程不满意(完全有效,大多数人是这样),或者您正在尝试锁定冗长的操作。应该将锁定最小化,以进行较短的较小操作,以防止不必要的线程等待,过度使用计算机资源,并实际上将性能降低到比单线程方法低的水平。