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 に答える