2016-07-27 48 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

確實沒有2個線程可以同時執行lockRead()方法的主體。但是讀寫器模式不需要正確工作並且具有預期的性能。

重要的是,如果沒有活動的寫入程序(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()方法,這是真的,只有一個線程可以同時執行lock.lockRead()。但只要該方法對其中一個線程返回,第二個線程也將能夠執行它。而致電lock.lockRead()發生得如此之快,你甚至不會注意到一個線程正在等待另一個線程。

重要的是兩個線程都能夠同時執行耗時更多的PerformWork()

+0

謝謝,這很有幫助 – Pintu