有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java更新程序配置

我有一个多线程程序,在启动时加载它的配置。然后通过线程的构造函数将配置传递给线程

但是现在我想定期加载一个新的配置实例,并将其传递给线程

一个想法是使thread类中对配置文件的引用不稳定。然后,当更新的配置实例可用时,调用updateupdate(Config c)方法

这是路吗?我将有糟糕的性能,因为每次线程需要一些设置,它必须做所有的易失性检查的东西

有更好的建议吗?最佳实践?也许不要让它变得易变,希望处理器不时地从主内存获取新对象


共 (4) 个答案

  1. # 1 楼答案

    您可以将所有配置值封装在一个不可变的对象中,当配置更改时,可以创建该对象的新实例,并通过侦听器或显式调用将其传递给线程。对象没有volatile字段,只有对象本身可以写入volatile变量(或AtomicReference

    没有其他同步机制的直接volatile方法是危险的:您可以读取一个重写了一半的配置

    在任何情况下,对应用程序的性能影响都可能可以忽略不计。如果你发现这真的是一个瓶颈,那么以后再考虑优化

  2. # 2 楼答案

    你可能想看看Commons Configuration

    A common issue with file-based configurations is to handle the reloading of the data file when it changes. This is especially important if you have long running applications and do not want to restart them when a configuration file was updated. Commons Configuration has the concept of so called reloading strategies that can be associated with a file-based configuration. Such a strategy monitors a configuration file and is able to detect changes. A default reloading strategy is FileChangedReloadingStrategy. It can be set on a file-based configuration as follows.

    ManagedReloadingStrategy is an alternative to automatic reloading. It allows to hot-reload properties on a running application but only when requested by admin. The refresh() method will force a reload of the configuration source.

  3. # 3 楼答案

    事实上,你确定那会有糟糕的表现吗

    如果说volatile主要用于阅读,那么它的性能并没有那么差。我建议首先尝试volatile,并测量性能下降,只有当它显著时,才进行任何返工

    如果您真的担心快速的易失性读取——那么在线程中运行方法时,您可以检查超时时间——如果上次配置读取已过60秒——然后重新读取它。逻辑将从update(Config c)反转为

    if(moreThan60SecondsPassed)
    {
    localConfig = configconfigHolder.getConfig();
    }
    

    此外,如果你使用非易失性配置,你不会得到半读配置。危险在于,可能会有一些线程永远看不到更新的值(关系之前不会发生)

    BW,您是否考虑在配置更新上重新创建线程?在这种情况下,您仍然可以通过构造函数传递config。这取决于您希望更新配置的频率

  4. # 4 楼答案

    您可以使用观察者模式通过侦听器通知线程新配置

    你无法避免不稳定的检查。也许是昂贵的(做一些性能测试),但你的程序会正常运行