ReadWriteLock
1.读写锁顶层接口
2.和Lock没有关系
ReentrantReadWriteLock
ReadWriteLock的实现类
成员变量:
ReentrantReadWriteLock.ReadLock readerLock (读锁)
ReentrantReadWriteLock.WriteLock writerLock (写锁)
Sync sync (同步器)
读锁和写锁都是实现 Lock 接口
实例代码
private ReadWriteLock lock = new ReentrantReadWriteLock();
public void method() {
lock.readLock().lock();
//lock.writeLock().lock();
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
//lock.writeLock().unlock();
}
}
ReentrantReadWriteLock构造方法
// fair 表示为是否为公平锁,默认为非公平
public ReentrantReadWriteLock(boolean fair) {
//创建同步器
sync = fair ? new FairSync() : new NonfairSync();
//把当前对象分别传入 到 读写锁中,主要是使用其 同步器
readerLock = new ReadLock(this);
writerLock = new WriteLock(this);
}
ReadLock.lock()
public void lock() {
// 因为读锁为共享锁,所以调用的是同步器的 acquireShared 方法 也就是AQS的这个方法
sync.acquireShared(1);
}
public final void acquireShared(int arg) {
//这个方法的结构很熟悉 和 acquire方法的 差不多
if (tryAcquireShared(arg) < 0)
//获取锁失败,进入等待队列
doAcquireShared(arg);
}
protected final int tryAcquireShared(int unused) {
/*
* Walkthrough:
* 1. If write lock held by another thread, fail.
* 2. Otherwise, this thread is eligible for
* lock wrt state, so ask if it should block
* because of queue policy. If not, try
* to grant by CASing state and updating count.
* Note that step does not check for reentrant
* acquires, which is postponed to full version
* to avoid having to check hold count in
* the more typical non-reentrant case.
* 3. If step 2 fails either because thread
* apparently not eligible or CAS fails or count
* saturated, chain to version with full retry loop.
*/
//获取当前线程
Thread current = Thread.currentThread();
//获取 state 的值
int c = getState();
//exclusiveCount 是获取独占锁(写锁)的个数
//假如 写锁存在 且独占线程不是当前的线程,直接返回 -1 获取锁失败
if (exclusiveCount (c) != 0 &&
getExclusiveOwnerThread() != current)
return -1;
// 获取读锁的个数
int r = sharedCount(c);
// readerShouldBlock 方法用来判断这个锁是否有资格获取锁 这个地方分为 公平锁和非公平锁 不同的实现方式
// r < MAX_COUNT 表示最大加锁的个数
//compareAndSetState 表示 CAS 操作是否成功
if (!readerShouldBlock() &&
r < MAX_COUNT &&
compareAndSetState(c, c + SHARED_UNIT)) {
if (r == 0) {
firstReader = current;
firstReaderHoldCount = 1;
} else if (firstReader == current) {
firstReaderHoldCount++;
} else {
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != getThreadId(current))
cachedHoldCounter = rh = readHolds.get();
else if (rh.count == 0)
readHolds.set(rh);
rh.count++;
}
return 1;
}
return fullTryAcquireShared(current);
}
writeLock.lock()
public void lock() {
sync.acquire(1);
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
/*
* Walkthrough:
* 1. If read count nonzero or write count nonzero
* and owner is a different thread, fail.
* 2. If count would saturate, fail. (This can only
* happen if count is already nonzero.)
* 3. Otherwise, this thread is eligible for lock if
* it is either a reentrant acquire or
* queue policy allows it. If so, update state
* and set owner.
*/
Thread current = Thread.currentThread();
int c = getState();
int w = exclusiveCount(c);
// c 不为0 表示 有线程持有了 锁,
// 写锁的 特性,这个锁的线程除非是自己线程,才能重入
if (c != 0) {
// (Note: if c != 0 and w == 0 then shared count != 0)
//必须是 当前线程
if (w == 0 || current != getExclusiveOwnerThread())
return false;
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
setState(c + acquires);
return true;
}
//判断是否有上锁的条件
// 1. writerShouldBlock 公平的和非公平的不同的处理,假如是公平锁 要判断是否在等待队列中不存在线程
//2. CAS 操作是否成功
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
// 设置独占线程 获取锁成功
setExclusiveOwnerThread(current);
return true;
}