2

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

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

4

3 回答 3

2

是的,通过将字段声明为volatile.

于 2012-03-25T23:28:03.350 回答
1

如果您的问题完全没问题,我认为 biziciop 的直截了当的回答。我的回答更多地说明了选择一种方式而不是另一种方式的哲学原因,因此请接受它的价值。

也许可以放宽要求,通过适当的测试,您可以证明实际上永远不会发生;也就是说,模拟您在测试中担心的情况。我喜欢不要过度设计事物以匹配最佳实践,因为它是最佳实践。

再说一次,如果由于您缺乏计划而导致并发访问错误,那么您(或某些未来的程序员,如果这是您将移交给其他人的系统)可能会诅咒您。

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

如果仅出于原因#3(我不知道这是否特别适用于您,但我确实看到许多程序员属于这一类),那么我会说这不是一个充分的理由,就其自己,放宽要求。如果它适用于#1或#2中的一个或两个,那么您可能会没事,只要您完全了解您正在做出的权衡。

于 2012-03-25T23:29:17.653 回答
1

如果这个类是通过 Spring 初始化的,那么这个定义就足够了。无需同步访问或使字段易失。

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

于 2012-03-25T23:34:38.490 回答