Java,多线程类,配置,避免同步

时间:2012-03-25 23:22:03

标签: java multithreading dependency-injection java-memory-model

假设我有一个需要配置,依赖注入等的类。

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的引用。在实践中可以放宽这个要求吗?

3 个答案:

答案 0 :(得分:2)

是的,将字段声明为volatile

答案 1 :(得分:1)

我认为,如果你的问题完全没问题,我可以直截了当地回答。我的回答更多地说明了选择一种方式而不是另一种方式的哲学原因,所以要把它用于它的价值。

可能能够通过适当的测试放松你可以证明的要求,实际上永远不会发生;也就是说,模拟您在测试中担心的情况。我不喜欢过度设计与最佳实践相匹配的东西,只因为它是最好的做法。

然后,如果由于您缺乏规划而导致并发访问错误,那么您(或未来的某个程序员,如果这是您将其他人转交给他人的系统)可能会诅咒您。

我想问题是,你为什么要避免这个要求?是(1)因为,在你的设计中,它永远不会真正发生吗?是否(2)使代码清晰,否则将更难以阅读/更难维护。或者它(3)是否因为多线程和同步的更深层次的特征?

如果仅仅是因为#3(并且我不知道这是否特别适用于你,但我确实看到许多程序员属于这个类别),那么我就说出来&# #39;它本身不足以放宽要求。如果它适用于#1或#2中的一个或两个,那么您可能没问题,只要您完全了解您正在进行的交易。

答案 2 :(得分:1)

如果通过Spring初始化此类,则此定义就足够了。无需同步访问或使字段不稳定。

实际上,如果已经执行了初始化,例如,在同步块内,则所有本地线程数据都已刷新到主存储器,并且所有线程都可以访问它们。