【发布时间】:2015-04-15 16:04:40
【问题描述】:
在我的 spring 项目中,在 context.xml 中,我定义了一个 bean,为此我调用了 init 方法,该方法创建了一个静态对象 leaderSelector。
init() {
leaderSelector= new customObject();
leaderSelector.start();
}
leaderSelector.start()将对象的属性hasLeadership修改为true。
只要服务器启动,就会调用上面的init方法。
我还有一个任务调度程序,它在同一个类callJobs()中调用不同的方法,我正在访问对象leaderSelector的属性hasLeaderShip,即false。
callJobs() {
if(leaderSelector.hasLeaderShip()) {
//do some important stuff
}
}
1.) init() 首先运行,并在一个线程中将对象leaderSelector 的hasLeaderShip 属性设置为true。
2.)任务调度程序随后调用callJobs()(在不同的线程中),当它访问对象leaderSelector的hasLeaderShip属性时,它是false。
对象leaderSelector 是静态的。但是创建了它的两个不同实例。我该如何解决这个问题。
完整程序
public class LeaderSelection extends LeaderSelectorListenerAdapter {
private static LeaderSelector leaderSelector;
@Autowired
private JobExecutionSender jobExecutionSender;
CuratorFramework client;
String path = "";
String zookeeperAddress = "/locks";
@Value("${cds.dl.timeout}")
private int sessionTimeout;
public LeaderSelection() {
}
private void start() {
leaderSelector.start();
}
public void init() {
client();
leaderSelector = new LeaderSelector(client, zookeeperAddress, this);
leaderSelector.requeue();
start();
}
public void callJobs() {
if (leaderSelector.hasLeadership()) {
jobExecutionSender.sendJobExecutions();
}
}
@Override
public void takeLeadership(CuratorFramework client) throws Exception {
log.debug("Has LeaderShip:" + leaderSelector.hasLeadership());
}
}
【问题讨论】:
-
一个 object 永远不是静态的 - variable 是。区分对象和变量非常重要。这些操作之间有什么内存障碍?任何同步块等?
-
考虑到静态对象概念不适用于这种情况,在不同时间在两个不同线程中访问同一个对象的最佳方法是什么?
-
“静态对象”根本不是一个概念,但听起来它应该工作,如果做得好——假设两个调用都使用相同的类加载器。如果你能在一个简短但完整的程序中演示这一点,而不是仅仅用文字描述代码,那将会有所帮助......
-
添加了完整的程序
-
这绝不是一个完整的程序。如果有人把你的代码复制到一个新的文本文件中,即使他们确实拥有所有相关的 jar 文件,它会编译和运行吗?不...不是我要求您提供完整的程序 - 我要求提供一个简短但完整的程序来演示问题,并且根本不必是您的原始代码...跨度>
标签: java multithreading spring concurrency thread-safety