我有一个多线程程序,可以在启动时加载其配置。然后通过构造函数将配置传递给线程。
但现在我想定期加载一个新的配置实例,并将其传递给线程。
一个想法是将线程类中的引用设置为volatile文件。然后,当更新的配置实例可用时,请调用更新update(Config c)
方法。
这是要走的路吗?我会有糟糕的表现,因为每次线程需要一些设置时,它必须做所有那些不稳定的检查。
一些更好的建议?最佳实践?也许不要让它变得不稳定并希望处理器不时从主存中取出那个新对象?
答案 0 :(得分:3)
您可以将所有配置值封装在单个不可变对象中,并在配置更改时创建对象的新实例,并通过侦听器或显式调用将其传递给线程。该对象没有volatile
个字段,只有对象本身可以用volatile
变量(或AtomicReference
)编写。
没有其他同步机制的直接volatile
方法很危险:您可以阅读中途重写的配置。
在任何情况下,对您的应用程序的性能影响可能微不足道。如果您发现这确实是一个瓶颈,请考虑稍后进行优化。
答案 1 :(得分:2)
实际上,你确定会有糟糕的表现吗?
如果挥发性物质主要用于阅读它的性能并不是那么糟糕。我建议首先尝试使用volatile并测量性能下降,然后仅在重要时尝试任何返工。
如果你真的担心快速的易失性读取 - 那么你在线程中运行方法就可以检查超时 - 如果自上次配置读取后经过了60秒 - 然后重新读取它。逻辑将从update(Config c)
转换为
if(moreThan60SecondsPassed)
{
localConfig = configconfigHolder.getConfig();
}
此外,如果您将使用非易失性 - 您将无法获得半读取配置。危险在于你可能会让一些线程永远不会看到更新的值(在关系之前没有发生)。
Bw,您是否考虑在配置更新中重新创建线程?在这种情况下,您仍然可以通过构造函数传递config。这取决于您想要更新配置的频率。
答案 2 :(得分:0)
您可以使用观察者模式通过侦听器通知新配置的线程。
你无法避免不稳定的检查。也许是昂贵的(做一些性能测试),但你的程序将正常运行。
答案 3 :(得分:0)
您可能需要查看Commons Configuration:
基于文件的配置的一个常见问题是在数据文件发生更改时处理重新加载。如果您有长时间运行的应用程序并且不希望在更新配置文件时重新启动它们,这一点尤为重要。 Commons Configuration具有所谓的重新加载策略的概念,可以与基于文件的配置相关联。这种策略监视配置文件并能够检测更改。默认的重新加载策略是FileChangedReloadingStrategy。它可以在基于文件的配置上进行设置,如下所示。
ManagedReloadingStrategy
是自动重新加载的替代方法。它允许在正在运行的应用程序上热重新加载属性,但仅在管理员请求时。 refresh()方法将强制重新加载配置源。