我有一个静态类,它为我提供了一个客户端。。
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;
}
代码执行示例:
- 线程A评估
_myClient == null
为true,进入块 - 线程B评估
_myClient == null
为true,进入块 - 线程A创建
Lazy<IClient>
对象并设置_myClient
字段 - 线程A退出
if
块 - 在线程B用新的
Lazy<IClient>
对象设置_myClient
字段之前,线程a访问_myCilent.Value
属性,从而创建Client
对象 - 线程B将
_myClient
字段设置为其新的Lazy<IClient>
对象 - 线程B访问
_myClient.Value
属性,创建第二个Client
对象 - 对
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)
子句中,创建多个对象,只分配一个。