【问题标题】:Java update program configurationJava更新程序配置
【发布时间】:2011-07-15 10:43:45
【问题描述】:

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

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

一个想法是使线程类中对配置文件的引用变为易失性。然后,当更新的配置实例可用时,调用更新update(Config c) 方法。

这是要走的路吗?我的性能会很糟糕,因为每次线程需要一些设置时,它都必须进行所有易失性检查。

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

【问题讨论】:

  • 更新配置有多重要?可以5秒刷新一次吗?在这种情况下,volatile 不会显着影响性能
  • 在每个线程知道新设置之前甚至可能需要 1 分钟。但我不想看到一半读取配置对象。

标签: java multithreading configuration volatile


【解决方案1】:

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

没有其他同步机制的直接volatile 方法很危险:您可以读取中途重写的配置。

无论如何,对您的应用程序的性能影响可能可以忽略不计。如果您发现这确实是一个瓶颈,请稍后再考虑优化。

【讨论】:

  • 如果一个线程完全加载配置(在此配置对象中按层次顺序排列的多个对象),是否可以读取半成品配置。然后同一个 config-loader 线程将这个新配置传递给所有其他线程?我不太明白哪些引用必须是易变的?再来说说Config-Loader-Thread、Worker-Thread和Config-Object(包含Config-Sub-Objects)
  • Config-Object 不需要任何 volatile 变量。在 Worker-Thread 中,您可以声明一个 AtomicReference<ConfigObject> config 字段。在 Config-Loader-Thread 中,您可以创建一个新的 Config-Object 实例,并将其存储在每个 Worker-Thread 的 config 变量中。
【解决方案2】:

实际上,你确定这会带来糟糕的表现吗?

如果 volatile 主要用于读取它的性能还不错。我建议先尝试 volatile 并测量性能下降,并且只有当它很重要时才进行任何返工

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

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

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

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

【讨论】:

    【解决方案3】:

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

    没有办法避免 volatile 检查的东西。也许很昂贵(做一些性能测试),但你的程序会正常运行。

    【讨论】:

      【解决方案4】:

      你可能想看看Commons Configuration

      基于文件的配置的一个常见问题是在数据文件更改时处理数据文件的重新加载。如果您有长时间运行的应用程序并且不想在更新配置文件时重新启动它们,这一点尤其重要。 Commons Configuration 具有所谓的重新加载策略的概念,可以与基于文件的配置相关联。这种策略监视配置文件并能够检测更改。默认的重新加载策略是 FileChangedReloadingStrategy。它可以在基于文件的配置上进行设置,如下所示。

      ManagedReloadingStrategy 是自动重新加载的替代方法。它允许在正在运行的应用程序上热重载属性,但仅在管理员请求时。 refresh() 方法将强制重新加载配置源。

      【讨论】:

        猜你喜欢
        • 2013-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-31
        相关资源
        最近更新 更多