6

この質問は、完璧な質問だと思うので、この質問の継続と拡張です。ローカル変数への割り当てはここでどのように役立ちますか?

Item 71この質問はofに基づいており、フィールド アクセスEffective Javaの目的でローカル変数を導入してパフォーマンスを高速化することが提案されています。volatile

private volatile FieldType field;  
FieldType getField() {  
    FieldType result = field;  
    if (result == null) { // First check (no locking)  
        synchronized(this) {   
        result = field;  
        if (result == null) // Second check (with locking)  
            field = result = computeFieldValue();  
        }  
    }  
    return result;  
}

だから、私の質問はより一般的です:

volatileフィールドの値をローカル変数に代入して、常にフィールドにアクセスする必要がありますか? (最高のパフォーマンスをアーカイブするため) .

つまり、いくつかの慣用句:

  1. いくつかのvolatileフィールドがありますvolatileField

  2. マルチスレッド メソッドでその値を読み取りたい場合は、次のようにする必要があります。

    1. 同じ型のローカル変数を作成します:localVolatileVariable
    2. volatile フィールドの値を割り当てます。localVolatileVariable = volatileField
    3. このローカル コピーから値を読み取ります。例:

      if (localVolatileVariable != null) { ... }
      
4

3 に答える 3

4

何らかのマルチステップ ロジックを実行する予定がある場合は、揮発性変数をローカル フィールドに割り当てる必要があります(もちろん、フィールドが変更可能であると仮定します)。

例えば:

volatile String _field;

public int getFieldLength() {
  String tmp = _field;
  if(tmp != null) {
    return tmp.length();
  }
  return 0;
}

のローカル コピーを使用しなかった場合_field、「if」テストと「length()」メソッド呼び出しの間で値が変化し、NPE が発生する可能性があります。

これは、複数の揮発性読み取りを行わないことによる速度向上の明らかな利点に加えてです。

于 2013-04-19T11:06:48.957 に答える
1

コインには表と裏があります。

一方では、volatile への代入はメモリ バリアのように機能し、JIT が computeFieldValue 呼び出しで代入を並べ替える可能性はほとんどありません。

一方、理論的には、このコードは JMM を壊します。何らかの理由で、一部のJVM は割り当てを使用して computeFieldValue を並べ替えることが許可されており、部分的に初期化されたオブジェクトが表示されるためです。これは、変数の読み取りが変数の書き込みの順序でない限り可能です。

field = result = computeFieldValue();  

前には起こらない

if (result == null) { // First check (no locking) 

「一度書けばどこでも実行できる」Java コードである限り、DCL は悪い習慣であり、避けるべきです。このコードは壊れており、考慮すべき点ではありません。

メソッドで volatile 変数の複数の読み取りがある場合、最初にそれをローカル変数に割り当てることで、よりコストのかかる読み取りを最小限に抑えることができます。しかし、パフォーマンスが向上するとは思いません。これはおそらく理論上の改善です。このような最適化は JIT に任せるべきであり、開発者の考慮事項ではありません。私はこれに同意します

于 2013-04-19T10:39:07.547 に答える
0

揮発性変数の読み取りを 2 回実行する可能性がある代わりに、1 回だけ実行します。volatile の読み取りは、通常の変数よりもおそらく少し遅くなります。しかし、たとえそうだとしても、ここではナノ秒の話です。

于 2013-04-19T12:59:21.503 に答える