10

以下は、Effective Java 2nd Edition のスニペットです。ここで著者は、次のコードは、結果変数を使用しない場合よりも 25% 高速であると主張しています。本によると、「この変数が行うことは、フィールドがすでに初期化されている一般的なケースで、フィールドが一度だけ読み取られるようにすることです。」. ローカル変数の結果を使用しない場合、値が初期化された後に比較してこのコードが高速になる理由を理解できません。どちらの場合でも、ローカル変数の結果を使用するかどうかに関係なく、初期化後に volatile 読み取りが 1 回だけ行われます。

// Double-check idiom for lazy initialization of instance fields 
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;
}
4

2 に答える 2

0

ローカル変数を使用せずに、ほとんどの呼び出しで効果的に

if(field!=null) // true
    return field;

そのため、2 つの揮発性読み取りがあり、1 つの揮発性読み取りよりも低速です。

実際、JVM は 2 つの揮発性読み取りを 1 つの揮発性読み取りにマージしても、JMM に準拠できます。しかし、JVM は指示されるたびに誠実な揮発性読み取りを実行することを期待しています。このコードを検討してください

volatile boolean ready;

do{}while(!ready); // busy wait

JVM が実際に変数を繰り返しロードすることが期待されます。

于 2013-06-19T02:29:53.003 に答える