本節一起學習ReentrantReadWriteLock類的源碼:
1、首先,可以看到ReentrantReadWriteLock類實現了ReadWriteLock接口,
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable
讀寫鎖ReadWriteLock接口定義了兩個方法:
public interface ReadWriteLock {
/**
* Returns the lock used for reading.
*
* @return the lock used for reading
*/
Lock readLock();
/**
* Returns the lock used for writing.
*
* @return the lock used for writing
*/
Lock writeLock();
}
2、接着看類中定義的變量:
/** Inner class providing readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
/** Inner class providing writelock */
private final ReentrantReadWriteLock.WriteLock writerLock;
/** Performs all synchronization mechanics */
final Sync sync;
定義了一個讀鎖對象,一個寫鎖對象,一個實現同步,我們依次看一下內部類 : ReadLock、WriteLock、Sync
3.內部類:ReadLock
3.1 首先看類的定義,實現了Lock接口
public static class ReadLock implements Lock
Lock接口定義了幾個方法:
void lock();獲取鎖
void lockInterruptibly() throws InterruptedException; 可中斷的獲取鎖
boolean tryLock();嘗試獲取鎖,如果鎖可用,則及時返回true,否則及時返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;如果在等待時間範圍內且線程未中斷,則嘗試獲取鎖,獲取到則返回true,否則返回false。
void unlock();釋放鎖
Condition newCondition(); 創建一個Condition --後續再跟這個接口。
3.2 類中的變量:
private final Sync sync;
3.3 構造函數:
/**
* Constructor for use by subclasses
*
* @param lock the outer lock object
* @throws NullPointerException if the lock is null
*/
protected ReadLock(ReentrantReadWriteLock lock) {
sync = lock.sync;
}
3.4 Lock接口方法實現:
public void lock() {
sync.acquireShared(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean tryLock() {
return sync.tryReadLock();
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.releaseShared(1);
}
public Condition newCondition() {
throw new UnsupportedOperationException();
}
可見,底層實現都是用的Sync類。
4.內部類:WriteLock
同讀鎖,具體Lock接口方法實現略不同:
public void lock() {
sync.acquire(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock( ) {
return sync.tryWriteLock();
}
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
public void unlock() {
sync.release(1);
}
public Condition newCondition() {
return sync.newCondition();
}
且讀鎖還有兩個方法:
public boolean isHeldByCurrentThread() {
return sync.isHeldExclusively();
}
官方翻譯爲:詢問此寫入鎖是否由當前線程保持
public int getHoldCount() {
return sync.getWriteHoldCount();
}
官方翻譯爲:詢問當前線程持有的寫入鎖的個數
5.內部類:Sync
執行所有同步機制,具體見另一篇博客
6. 構造方法
默認使用的非公平版本
/**
* Creates a new {@code ReentrantReadWriteLock} with
* default (nonfair) ordering properties.
*/
public ReentrantReadWriteLock() {
this(false);
}
/**
* Creates a new {@code ReentrantReadWriteLock} with
* the given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantReadWriteLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
7.常用的方法
public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }
public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; }