2011-11-11 17 views
3

java.util.concurrencyパッケージのソースコードを参照しながら、私が以前見たことがないReentrantLockの慣用的な使用に気付きました。メンバーRentrantLock変数は、これらのメソッドは常にローカル変数参照によって参照されていました。 java.util.concurrent.ThreadPoolExecutorReentrantLockをConcurrencyパッケージで慣用的に使用する

private final ReentrantLock mainLock = new ReentrantLock(); 
... 
// why a local reference to final mainlock instead of directly using it? 
final ReentrantLock mainLock = this.mainLock; 
mainLock.lock(); 
try { 
...  
} finally { 
    mainLock.unlock(); 
} 

から

スタイル#1例えばしかしながら、他の場所で最後のメンバ変数は、最初にローカル参照を取得することなく、直接使用されます。

スタイル#2実践

でのJava並行処理から
private final Lock lock = new ReentrantLock(); 
... 
// here the final lock is used directly 
lock.lock(); 
try { 
... 
} finally { 
lock.unlock(); 
} 

私はスタイル#1オーバースタイル#2を使用する利点があるかを理解したいと思いますか?

おかげ

アップデート最初のパフォーマンスを識別するための応答のすべてのための

おかげで、特にベン・マネス。 は、結果として、私はコメントダグによると「cache finals across volatiles

  • 2003年に

    1. ダグ・リーはこのイディオムを紹介し、次の追加の詳細を発見することができた、それは「for performance-critical code like that inside j.u.c.」で、そうではありません」しながら、練習をお勧めします」、と彼 『does not discourage it eitherdon't worry
  • +0

    私が知る限り、何もありません。これは「最終的な」メンバーなので、ローカル参照を取得することはできません。 2つの異なるプログラマーがコードのこれらのセクションに取り組んだことを示しているかもしれません。 – Gray

    +0

    以前のバージョンのコードで 'mainLock'が非finalとして定義されていない限り、ローカル変数を取る理由がわかりません。 – Bringer128

    +2

    バイトコードの最適化に関するこのトリックの詳細については、この[スレッド](http://old.nabble.com/Making-copy-of-a-reference-to-ReentrantLock-tt30730392.html#a30733348)を参照してください。 –

    答えて

    2

    ベン・メインズはトンをリンク』

  • ブライアン・ゲッツ(JCIPの作者)も、それは、パフォーマンス・クリティカルなアプリケーションのためである場合を除きことに同意します』 o discussionは、JITの最適化について述べたコメントに含まれています。明らかに、ホットスポットコンパイラはリフレクションまたはUnsafeクラスを使用して変更できるため、finalフィールドの負荷を最適化しません。

    したがって、このメカニズムは、JITがロックインスタンスの負荷を最適化できるように、速度を少し改善します。彼らはどの最適化が起こるのか詳細には触れていませんが、最適化は主記憶からインスタンスを再ロードするのを防ぐためのものです。これにより、スレッドは再入可能ロックをペナルティなしに複数回使用することができます。

    残念ながら、この回答はメーリングリストの議論に基づいた推測です。誰かが私を修正することができれば先に行ってください!

  • +0

    詳細については、この[ブログの投稿](http://www.azulsystems.com/blog/cliff/2011-10-27-final-fields-part-2)を参照してください。 –

    関連する問題