【发布时间】:2016-02-26 23:58:47
【问题描述】:
我写了一个风暴拓扑,并将它的工人数设置为 1。 所以,我认为它的所有组件都应该在同一个进程中运行。而且我想在拓扑中的多个组件之间共享一个公共对象,所以我使用单例模式: 1,我在打开唯一的 spout 时初始化单例对象。 2、然后,我通过调用getInstance()函数在其他组件中使用单例对象。
但是,我发现我会在不同的组件之间得到不同的对象。
感谢您的回复。问题的关键代码如下: 单例类代码:
public class TraceApplicationContext {
private volatile static TraceApplicationContext instance = new TraceApplicationContext();
private TraceApplicationContext() {
}
public static TraceApplicationContext getInstance() {
return instance;
}
}
SpoutA 类代码:
public class SpoutA extends BaseRichSpout {
public void open(Map map, TopologyContext topologyContext, SpoutOutputCollector spoutOutputCollector) {
TraceApplicationContext.getInstance().init();
}
}
BoltA 代码:
public class BoltA extends BaseRichBolt {
private static JedisCluster jedisCluster = TraceApplicationContext.getInstance().getJedisCluster();
}
BoltB 代码:
public class BoltB extends BaseRichBolt {
private static JedisCluster jedisCluster = TraceApplicationContext.getInstance().getJedisCluster();
}
在SpoutA中初始化TraceApplicationContext单例对象后,查看TraceApplicationContext.getInstance().getJedisCluster()返回的对象,不为null。但是我在BoltA和BoltB中查看,TraceApplicationContext.getInstance().getJedisCluster()返回的对象为null。
有没有人遇到过同样的问题或知道这样的问题有什么问题?
请帮忙! 谢谢!
【问题讨论】:
-
请出示一些代码,否则我们将无法提供帮助。
-
我已经添加了我的密钥代码,请帮助。谢谢!
-
要仔细检查的是
TraceApplicationContext.class.getClassLoader()是否在所有上下文中返回相同的类加载器实例。任何单例都只限于其类加载器,而不是整个 JVM。 -
在storm中使用单例可能会很棘手。认为在大多数情况下,每个类加载器(每个 JVM 工作程序)都有一个单例,而不是所有集群的单例。此外,不鼓励在风暴集群中的螺栓/喷口之间共享对象(锁、线程安全、可变性......),如果可能的话,我认为最好在风暴中删除任何单例的使用。
标签: java singleton apache-storm