同步构造是否正确?

时间:2010-09-28 11:06:36

标签: c# synchronization

我有一个多线程应用程序。线程使用ABC.Connector。我希望一次只有一个线程可以访问Connector属性。

class ABC
{
    /// <summary>
    /// Synchronization object.
    /// </summary>
    static object _syncObject = new object();

    static DataAccess _connector;
    /// <summary>
    /// Global object for data access.
    /// </summary>
    public static DataAccess Connector
    {
        get
        {
            lock (_syncObject)
            {
                return _connector.CreateCopy(); // get a copy of original _connector
            }
        }
        set
        {
            lock (_syncObject)
            {
                _connector = value;
            }
        }
    }
}

这是对的吗?

2 个答案:

答案 0 :(得分:1)

嗯,这肯定会使Connector属性获取并设置为线程安全(尽管我将_syncObject设为只读)。但是,它不会使DataAccess线程安全......当线程获取并设置属性时,互斥锁将仅应用

换句话说,如果两个线程都这样做:

ABC.DataAccess.DoSomeLongRunningOperation();

然后DoSomeLongRunningOperation()仍将由两个线程同时运行。如果该操作不是线程安全的,那么它仍然是一个问题。

如果您一次只想要一个线程使用 DataAccess,那么您可以写:

public static void UseConnector(Action<DataAccess> action)
{
    lock (_syncObject)
    {
        action(_connector);
    }
}

然后如果两个线程都这样做:

ABC.UseConnector(access => access.DoLongRunningOperation());

然后DoLongRunningOperation()一次只能在一个线程中运行。你仍然遇到行为不端的客户可以写的问题:

DataAccess naughty = null;
ABC.UseConnector(access => naughty = access);
// Haha! I've circumvented your thread safety!
naughty.DoLongRunningOperation();

...但希望这对你来说不是问题。

答案 1 :(得分:1)

是的,这通常是正确的。但是请注意,在Connector get返回_connector引用之后,对它的访问是不同步的。