我有一个多线程应用程序。线程使用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;
}
}
}
}
这是对的吗?
答案 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引用之后,对它的访问是不同步的。