Java更新程序配置
我有一个多线程程序,在启动时加载其配置。然后配置通过线程的构造函数传递给线程。
但现在我想定期加载一个新的配置实例,并将其传递给线程。
一种想法是使线程类中对配置文件的引用可变。然后,当更新的配置实例可用时,调用更新 update(Config c) 方法。
这是要走的路吗?我的性能会很糟糕,因为每次线程需要一些设置时,它都必须执行所有易失性检查。
有一些更好的建议吗?最佳实践?也许不要让它变得易失,并希望处理器不时从主内存中获取该新对象?
I have a multithreaded program that loads its configuration on startup. The configuration is then handed down to the threads via their constructors.
But now I want to load one new config instance regularly, and pass it to the threads.
One idea would be to make the reference in the thread class to the config file volatile. Then, when an updated config instance is available, call a update update(Config c)
method.
Is this the way to go? I will have terrible performance because every time the thread needs some setting it has to do all that volatile checking stuff.
Some better suggestions? Best practice? Maybe don't make it volatile and hope that the processor fetches that new object from main memory from time to time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以将所有配置值封装在一个不可变对象中,当配置更改时创建该对象的新实例,并通过侦听器或显式调用将其传递给线程。该对象没有
易失性
字段,只有对象本身可以写入易失性
变量(或AtomicReference
)。没有其他同步机制的直接
易失性
方法是危险的:您可能会读取半重写的配置。无论如何,对应用程序的性能影响可能可以忽略不计。如果你发现这确实是一个瓶颈,稍后再考虑优化。
You could encapsulate all of your configuration values in a single immutable object, and when the configuration changes create a new instance of the object, and pass it to the threads, through listeners or explicit calling. The object has no
volatile
fields, only the object itself could be written in avolatile
variable (or anAtomicReference
).The direct
volatile
approach with no other synchronization mechanisms is dangerous: you could read a halfway-rewritten configuration.In any case, the performance impact on your application is likely to be negligible. Think about optimization later, if you find this is really a bottleneck.
事实上,你确定这会带来糟糕的表现吗?
如果 volatile 主要用于读取,那么它的性能还不错。我建议首先尝试 volatile 并测量性能下降情况,只有当情况很严重时才进行返工。
如果您真的担心快速易失性读取 - 那么在线程中运行方法时,您可以检查超时 - 如果自上次配置读取以来已经过去了 60 秒 - 然后重新读取它。逻辑将从
update(Config c)
反转为另外,如果您将使用非易失性 - 您将不会获得一半的读取配置。危险在于您可能会让某些线程永远看不到更新的值(没有发生之前的关系)。
Bw,您是否考虑过在配置更新时重新创建线程?在这种情况下,您仍然可以通过构造函数传递配置。这取决于您想要更新配置的频率。
Actually, are you sure that will have terrible performance?
If volatile used mostly for reading it's performance is not that bad. I'd recommend to try volatile first and measure performance degradation and only if it's significant then do any rework.
If you are really worrying about rapid volatile reads - then in you run method in thread you could have check for timeout - if 60 seconds passed since last config read - then reread it. Logic will reversed from
update(Config c)
, toAlso, if you'll be using non volatile - you won't get half read config. The danger is that you could have some threads not see updated value forever (no happens-before relationship).
Bw, did you consider recreating threads on config update? In this case you still could pass config through constructor. It depends on how often you want to update configuration.
您可以使用观察者模式通过侦听器向线程通知新配置。
您无法避免易失性检查。也许很昂贵(做一些性能测试),但你的程序会正确运行。
You can use observer pattern to notify the threads of new config via listeners.
There is no way you can avoid volatile checking stuff. Maybe is expensive(do some performance tests) but your program will run correctly.
您可能需要查看公共配置:
You may want to look at Commons Configuration: