静的変数を初期化するときに、ローカル変数を使用します

ジョン・マクレーン:

ソースコードではjava.util.ScannerIこれらの静的ユーティリティメソッドを見つけました:

private static Pattern separatorPattern() {
    Pattern sp = separatorPattern;
    if (sp == null)
        separatorPattern = sp = Pattern.compile(LINE_SEPARATOR_PATTERN);
    return sp;
}

private static Pattern linePattern() {
    Pattern lp = linePattern;
    if (lp == null)
        linePattern = lp = Pattern.compile(LINE_PATTERN);
    return lp;
}

なぜそれがこのような複雑な方法で行われていないだけで、言いました、

private static Pattern linePattern() {
    if (linePattern == null)
        linePattern = Pattern.compile(LINE_PATTERN);
    return linePattern;
}

(ローカル変数を使用してのポイントは何だったlpここでは)?これは、最適化技術のいくつかの種類ですか?それとも同時変更に対する予防策?しかし、linePatternに設定することはできませんnull。このメソッドは、それが変更された唯一の場所であるとして再び。

ティロ:

私は、彼らが読んでから避けたいと思いますvolatile二度のフィールド。

  • それがあるかどうかを確認するには、一度 null
  • 一度用 return

彼らのバージョンでは、彼らだけ

  • 一度ローカル変数にそれを読んで
  • ローカル変数がnullでないことを確認します
  • そのローカル変数を返します

それは初期化が完了する前に、メソッドが同時に呼び出された場合、数時間または最大で - 最適化は一度だけ起こる「初期セットアップパス」よりも信じられないほど、より頻繁に起こる「ハッピーパス」のためです。

それとも同時変更に対する予防策?

そのような予防策はありません。あなたが呼び出す場合linePattern、それは静的な揮発性のフィールドの設定が完了する前に、パターンを複数回作成した(ただし、の細かいこと)され、同時に、別のインスタンスが返され、それらのランダムな1は以来、罰金もだこと(周りに固執するように選択されます彼らは)同じです。

それを防ぐために、任意の対策だけでこれだけの状況で行われるべきである私たちの「ハッピーパス」にコストを追加する場合は、実際にいくつかの理由でシングルトンでなければなりませんでした。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=171803&siteId=1