我试图使用单个客户端实例来创建多个索引。下面是相同的代码。但每次我将实例作为null并且它创建一个新实例。请让我知道我做错了什么
单身实例:
public class ESClientSingleton {
public static Client instance ;
private ESClientSingleton()
{}
public static Client getInstance()
{
if (instance == null)
{
System.out.println("the instance is null...");
ImmutableSettings.Builder settings = ImmutableSettings.settingsBuilder();
settings.put("node.client", true);
settings.put("node.data", false);
settings.put("node.name", "node-client");
settings.put("cluster.name", "elasticsearch");
settings.build();
instance = new TransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress("10.203.251.142", 9300));
//instance = client;
System.out.println("return the client");
return instance;
}
return instance;
}
}
调用方法:
public static IndexResponse insertESDocument(String nodeName, String json) throws MasterNotDiscoveredException, SocketException
{
Client client = ESClientSingleton.getInstance();
logger.debug("calling the es client");
logger.debug("the json received as == "+json);
IndexResponse response = client.prepareIndex("aricloud-nodes","node-entry",nodeName )
.setSource(json)
.execute()
.actionGet();
logger.debug("the document is successfully indexed...");
System.out.println("the document is indexed...");
//client.close();
return response;
}
答案 0 :(得分:1)
要实现Singleton模式,请使用 enum 而不是类。 enum具有许多内置优势,这有助于我们简化单例实现。 有关更多信息,请参阅joshua bloch的Effective Java。
答案 1 :(得分:0)
这确实是为elasticsearch集群调用单例客户端对象实例的正确方法。我在webapp上遇到了一些问题,现在也在使用。
然而,这可以成为寻找类似答案的人的一个例子。
答案 2 :(得分:0)
在多线程环境中,检查实例是否为null可能还不够。
您可以拥有一个竞速条件,其中有2个或更多个线程并行执行此检查,第二个尝试也尝试实例化该对象,因为第一个没有完成分配。 有很多方法可以解决这个问题,最常见的方法是将实例声明为 volatile ,并将if放在 synchronized块中:
public class SingletonDemo {
private static volatile SingletonDemo instance;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null ) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
或者由Jayan K提出的枚举解决方案。 更多详情:https://en.wikipedia.org/wiki/Singleton_pattern