2016-07-27 2 views
0

多くのチュートリアルでは、再入可能でないReadWriteLockの実装より下に来ました。ReadWriteLocks-読み込みロックを取得するために複数のリーダーをサポートする方法

public class ReadWriteLock{ 

    private int readers  = 0; 
    private int writers  = 0; 
    private int writeRequests = 0; 

    public synchronized void lockRead() throws InterruptedException{ 
     while(writers > 0 || writeRequests > 0){ 
     wait(); 
     } 
    readers++; 
    } 

    public synchronized void unlockRead(){ 
     readers--; 
     notifyAll(); 
    } 

    public synchronized void lockWrite() throws InterruptedException{ 
     writeRequests++; 

     while(readers > 0 || writers > 0){ 
     wait(); 
     } 
     writeRequests--; 
     writers++; 
    } 

    public synchronized void unlockWrite() throws InterruptedException{ 
     writers--; 
     notifyAll(); 
    } 
} 

質問:

このクラスのオブジェクトは(lockを言う)の同期のためにすべてのリーダライタスレッド間で共有されています。

リーダーT1がlock.lockRead()を呼び出し、これがロックオブジェクトのロックを取得し、同時にリーダーT2が同じオブジェクトのlockRead()を呼び出したとします。しかし、T1はすでにオブジェクトをロックしているため、T2はブロックされ、キュー内で待機する必要があります。

コードでは、複数の読者が同時にreadLockをどのように設定できるのですか?

私がこれを間違えたときに私に教えてください。

答えて

2

lockRead()メソッドの本体を2つのスレッドが同時に実行できないことは事実です。しかし、これはリーダ/ライタのパターンが正しく動作し、期待される性能を発揮するためには必要ではありません。

重要なことは、アクティブライターがない場合(waitが呼び出されない場合)、lockRead()メソッドが迅速に返されることです。メソッドが終了するとロックが解除され、別のスレッドも読み取りロックを取得できるようになります。

はい、読み取りロックの取得行為(インクリメントreaders)がシリアル化されます。しかし、それは非常に迅速に起こる、それはうまく動作します。説明するために

private ReadWriteLock lock = new ReadWriteLock(); // this instance is shared by all threads 

public void ReadSomething() { 
    try { 
     lock.lockRead(); // serialized, but very quick 

     PerformWork(); // potentially slower, but is concurrent 
    } finally { 
     lock.unlockRead(); // serialized, but very quick 
    } 
} 

を2つのスレッドが正確に同じ時刻に上記ReadSomething()方法を実行しようとすると、それは一度に1つのスレッドしかlock.lockRead()を実行できるようになるというのは本当です。しかし、そのメソッドがスレッドの1つを返すとすぐに、2番目のスレッドも同様にそれを実行することができます。そして、lock.lockRead()への呼び出しは非常に速く行われ、あるスレッドがもう一方のスレッドを待っていることに気づくことさえできません。

重要なことは、両方のスレッドが同時に時間のかかるPerformWork()を実行できることです。

+0

ありがとうございました – Pintu

関連する問題