【问题标题】:How to solve two threads and two instances of static variable scenario?如何解决两个线程和两个实例的静态变量场景?
【发布时间】: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() 首先运行,并在一个线程中将对象leaderSelectorhasLeaderShip 属性设置为true

2.)任务调度程序随后调用callJobs()(在不同的线程中),当它访问对象leaderSelectorhasLeaderShip属性时,它是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


【解决方案1】:

试试

1) 同步访问修改hasLeadership的方法

2) 将您的 leaderSelector 转换为 Singleton 类。见:http://www.javaworld.com/article/2073352/core-java/simply-singleton.html

【讨论】:

  • 这个很有趣。将尝试。
【解决方案2】:

线程之间没有内存同步,因此 JVM 不会跟踪分配。使变量volatile

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 2014-02-03
    • 2013-07-09
    相关资源
    最近更新 更多