2011-12-08 9 views
7

この質問にいくつか答えを示唆したように:私はReentrantReadWriteLockを実装し、素晴らしいスピードアップを見ReadWriteLockはsynchronizedキーワードを不要にしますか?

What is the name of this locking technique?

(私はそこにいくつかのロック競合が1つの私のクラスにいたとリエントラントロックを使用すると、ヘルプ速度の事をやった知っていましたアップ)。

しかし、私は疑問に思っています:クラス内のすべてのアクセス(読み取りと書き込みの両方)が最初に読み取りロックまたは書き込みロックをロックすることによって行われた場合、同期化キーワードはそのクラスではもう使用されていますか?例えば

は、ここには同期キーワードはありませんhttp://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

class RWDictionary { 
    private final Map<String, Data> m = new TreeMap<String, Data>(); 
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); 
    private final Lock r = rwl.readLock(); 
    private final Lock w = rwl.writeLock(); 

    public Data get(String key) { 
     r.lock(); 
     try { return m.get(key); } 
     finally { r.unlock(); } 
    } 
    public String[] allKeys() { 
     r.lock(); 
     try { return m.keySet().toArray(); } 
     finally { r.unlock(); } 
    } 
    public Data put(String key, Data value) { 
     w.lock(); 
     try { return m.put(key, value); } 
     finally { w.unlock(); } 
    } 
    public void clear() { 
     w.lock(); 
     try { m.clear(); } 
     finally { w.unlock(); } 
    } 
} 

で見られる一の公式のJava 1.6の例です。

このようなロックのポイントの1つは、他の方法(この場合はより速くを同期するよりも速いですが)の背後にある技術的な説明は何ですか?

すべての取得/更新メソッドのクラスで読み書きロックを使用すると、キーワードをこれらのメソッドと同期させて置き換えますか?

+0

私はあなたが 'synchronize(this)'のようにインスタンス上で同期していたと仮定します。代わりに、2つの異なるオブジェクト(読み込み用と書き込み用)で同期させると、同じパフォーマンスが達成されます。 'this'同期では、' put'が処理されているときに、不必要に 'get'も待機します。異なるロックオブジェクトを使用すると、この競合はなくなります。 – srkavin

+0

ほとんどのマップの実装では、putの実行中に待機する必要があります。 – Affe

+0

@srkavin競合は消滅していますが、メモリの可視性も保証されます。お互いに同期されていないので、 'get'は' put'から部分的な更新を見た可能性があります。 – yshavit

答えて

10

あなたはReadWriteLockのJavadocを読んでいる場合、およびロックの、彼らは、特にロックが​​キーワードと同じメモリのセマンティクスを提供する必要があると言う:

すべてのLock実装が同じメモリ同期セマンティクスを施行しなければなりませんJava言語仕様第3版(17.4メモリーモデル)で説明したように、内蔵のモニターロックによって提供:

(これはロックのjavadocからだ。ReadWriteLockは、その意味を記述するためにロックを指す。)

はい、それは​​キーワードに置き換わります。実際には、あなたのコード内のすべての​​ブロックをLockで置き換えて、同じセマンティクスを持つことができます(そして、jvmに応じて、場合によっては小さなパフォーマンス向上にもなります)。しかし、ロックのいずれかをロック解除することを忘れてしまった場合は、プログラムをデッドロックする可能性があります。

これの多くはノンブロッキングアルゴリズムは何の力

compare-and-swapている彼らの心)あなたはvolatileフィールドに書き込む場合は、その後にそのフィールドを読み取る任意のスレッドがに持っていることを指定volatileフィールドのメモリセマンティクスと組み合わせあなたがそれを書いたときに見た世界の少なくとも同じ状態を見てください。これらのツールはかなり高速なコードを作ることができますが、微妙で簡単に間違っていることもあります。より高いレベルで構造体(使用しているReadWriteLockなど)

関連する問題