C#静态方法是否同步并锁定



我有一个静态类,它为我提供了一个客户端。。

public static ClientFactory {
private static Lazy<IClient> _MyClient;
public static IClient GetClient(ICache cache) {
if (_MyClient == null) {
_MyClient = new Lazy<IClient>(() => CreateClient(cache));
}
return _MyClient.Value;
}
private static IClient CreateClient(ICache cache) {
// code that takes 1-2 seconds to complete
return new Client(cache);
}
}

通过编写这样的代码,我是否有可能创建2个或多个客户端?第二个客户端将覆盖第一个客户端的位置?

我应该如何更新我的代码,以便每个应用程序只调用一次构造函数?

谢谢。

是的,您的代码可以创建多个Client对象。使用静态构造函数创建Lazy<IClient>实例:

public static ClientFactory
{
...
static ClientFactory()
{
_myClient = new Lazy<IClient>(() => CreateClient());
}
public IClient GetClient() => _myClient.Value;
}

代码执行示例:

  1. 线程A评估_myClient == null为true,进入块
  2. 线程B评估_myClient == null为true,进入块
  3. 线程A创建Lazy<IClient>对象并设置_myClient字段
  4. 线程A退出if
  5. 在线程B用新的Lazy<IClient>对象设置_myClient字段之前,线程a访问_myCilent.Value属性,从而创建Client对象
  6. 线程B将_myClient字段设置为其新的Lazy<IClient>对象
  7. 线程B访问_myClient.Value属性,创建第二个Client对象
  8. GetClient的所有后续调用都将返回Client的第二个实例

是的,有机会,考虑这个例子,根据您的输入,运行这个简单的程序可能会导致初始化一个或两个客户端(运行多次查看(:

void Main()
{
System.Threading.Tasks.Parallel.Invoke(
() => ClientFactory.GetClient(1),
() => ClientFactory.GetClient(2));  
}
// You can define other methods, fields, classes and namespaces here
public static class ClientFactory {
private static Lazy<IClient> _MyClient;
public static IClient GetClient(int init) {
Console.WriteLine(_MyClient == null);
if (_MyClient == null) {
Console.WriteLine(init);
_MyClient = new Lazy<IClient>(() => CreateClient());
}       
return _MyClient.Value;
}
private static IClient CreateClient() {
// code that takes 1-2 seconds to complete
return new Client();
}
}
public interface IClient {
}
public class Client : IClient {
public Client() {
Console.WriteLine("Client constucrtor");
}
}

两个线程可能同时在if (_MyClient == null)子句中,创建多个对象,只分配一个。

最新更新