11

私はJavaでコードの並べ替えや競合条件について質問します。 Lockは出来上がる関係を保証しますか?

は2つの以上のスレッドが同時に workForThread()を実行すると、私は次のコードがあるとします。

public class Job { 
    private Lock lock = new ReentrantLock(); 
    private int sharedObject = 1; 
    public void workForThread() { 
     lock.lock(); 
     try { 
      sharedObject++; 
     } finally { 
      lock.unlock(); 
     } 
    } 
} 

それはJVMが間違った順序でこれを実行することができることは可能ですか?たとえば、次の並べ替えが可能ですか?

sharedObject++; 
lock.lock(); 
lock.unlock(); 

または、ロックの順序が変更されないことは保証されていますか?

+0

一般に、JVMは、リオーダリングが「最終的な一貫性」につながり、パフォーマンスを向上させることが判明した場合、メモリバリア命令間の命令を並べ替えることができます。並べ替えによって最終的な整合性が得られない場合、JVMは命令の順序を変更しません。 – TheLostMind

+0

関連:http://stackoverflow.com/questions/2576443/java-memory-model-reordering-and-concurrent-locks?rq=1 – Thilo

+1

@Ryu「Lock」のインスタンスを作成することはできませんインタフェース。私は 'ReentrantLock'やその他のロックインターフェース' Lock'の実装をインスタンス化することを意図していたと思いますか?そうでない場合は、あなたの 'Lock'実装の様子を見せてくれますか? – CKing

答えて

7

のはJavaのドキュメントLockインタフェースについて述べているものを見てみましょう:内蔵のモニターロックによって提供されるように説明したよう

すべてのLock実装は、 セマンティクス同じメモリ同期を強制する必要がありますロックの操作が成功した場合、同じメモリ同期 のロック操作が成功したとみなされます。

成功したロック解除操作には、 ロック解除操作の成功と同じメモリ同期効果があります。

あなたの質問に対する答えははいです。 Lockは、通常の​​ブロック/メソッドと同じ並べ替え順序を与えます。

+0

しかし、あなたは 'Job'インスタンスに対して' Lock'インスタンス上で 'synchronize'していません。それでも動作しますか? – Thilo

+0

@Thiloはい。すべてのスレッドが同じ 'Lock'を使用する限り。 (私は 'Lock'はJDKによって提供される組み込みインターフェースだと仮定しています) – CKing

+0

あなたが正しいと思います。 JMMは、BがAが解放したロックを取得した場合、スレッドBはスレッドAによって行われたすべてを見ることができると述べています。 (事故前のリレーションシップ)。それがうまくいかなかった場合、これらの専用の 'private final Object lock = new Object()'を同期させるというGood Practiceはうまくいきません。 – Thilo

関連する問題