假设我有一个需要配置,依赖注入等的类。
public class MyClass {
private String someConfig;
private SomeMutableClass anotherConfig;
MyClass() {
// impractical to set everything in ctor
// otherwise I'd declare someConfig final and
// not worry about MT safety.
}
void setConfig(cfg) {
this.someConfig = cfg;
}
void anotherConfig(cfg) {
this.anotherConfig = cfg;
}
...
// below is code that uses the config set before, possibly by
// multiple threads.
}
这是一个人为的例子,但如果我不能轻易地完成ctor中的所有配置怎么办? 假设配置在执行的早期完成,并且不会改变。严格来说,由于内存模型,我必须同步所有对someConfig的引用。在实践中可以放宽这个要求吗?
答案 0 :(得分:2)
是的,将字段声明为volatile
。
答案 1 :(得分:1)
我认为,如果你的问题完全没问题,我可以直截了当地回答。我的回答更多地说明了选择一种方式而不是另一种方式的哲学原因,所以要把它用于它的价值。
你可能能够通过适当的测试放松你可以证明的要求,实际上永远不会发生;也就是说,模拟您在测试中担心的情况。我不喜欢过度设计与最佳实践相匹配的东西,只因为它是最好的做法。
然后,如果由于您缺乏规划而导致并发访问错误,那么您(或未来的某个程序员,如果这是您将其他人转交给他人的系统)可能会诅咒您。
我想问题是,你为什么要避免这个要求?是(1)因为,在你的设计中,它永远不会真正发生吗?是否(2)使代码清晰,否则将更难以阅读/更难维护。或者它(3)是否因为多线程和同步的更深层次的特征?
如果仅仅是因为#3(并且我不知道这是否特别适用于你,但我确实看到许多程序员属于这个类别),那么我就说出来&# #39;它本身不足以放宽要求。如果它适用于#1或#2中的一个或两个,那么您可能没问题,只要您完全了解您正在进行的交易。
答案 2 :(得分:1)
如果通过Spring初始化此类,则此定义就足够了。无需同步访问或使字段不稳定。
实际上,如果已经执行了初始化,例如,在同步块内,则所有本地线程数据都已刷新到主存储器,并且所有线程都可以访问它们。