顾名思义,该类实现的是可重入的的WriterPreferenceReadWriteLock。允许readers和writers在各自线程里反复获得读或写的锁。这种方法主要用在
该类是WriterPreferenceReadWriteLock的子类,与父类大体流程一致,但是startWrite,startRead ,allowReader ,endRead和endWrite被重写,下面逐一解释。
先看看新添加的成员变量
- /**在activeWriter线程里,有多少次write锁的控制权被获取**/
- protected long writeHolds_ = 0;
- /**存放的每个reader线程共申请获得多少次读控制,key值是thread对象,value是次数**/
- protected HashMap readers_ = new HashMap();
- /*一个int的常量缓存*/
- protected static final Integer IONE = new Integer(1);
/**在activeWriter线程里,有多少次write锁的控制权被获取**/
protected long writeHolds_ = 0;
/**存放的每个reader线程共申请获得多少次读控制,key值是thread对象,value是次数**/
protected HashMap readers_ = new HashMap();
/*一个int的常量缓存*/
protected static final Integer IONE = new Integer(1);
再来看看Reader部分的重写函数
- protected boolean allowReader() {
- //与父类的变化在于,activeWriter_ == Thread.currentThread(),
- //也就是说当本线程已经获得写控制的时候,返回true
- return (activeWriter_ == null && waitingWriters_ == 0) ||
- activeWriter_ == Thread.currentThread();
- }
- protected synchronized boolean startRead() {
- Thread t = Thread.currentThread();
- //查看本线程是否已经获得读控制
- Object c = readers_.get(t);
- if (c != null) { // already held -- just increment hold count
- //计数+1
- readers_.put(t, new Integer(((Integer)(c)).intValue()+1));
- ++activeReaders_;
- return true;
- }
- //调用allowReader
- else if (allowReader()) {
- //将本线程获锁次数纪录在readers_这个map里
- readers_.put(t, IONE);
- ++activeReaders_;
- return true;
- }
- else
- return false;
- }
- protected synchronized Signaller endRead() {
- Thread t = Thread.currentThread();
- Object c = readers_.get(t);
- if (c == null)
- throw new IllegalStateException();
- --activeReaders_;
- if (c != IONE) { // 多于一个读线程有控制权,more than one hold; 计数递减
- int h = ((Integer)(c)).intValue()-1;
- Integer ih = (h == 1)? IONE : new Integer(h);
- readers_.put(t, ih);
- return null;
- }
- else {
- readers_.remove(t);
- if (writeHolds_ > 0) // 本线程还有写锁在占用控制权
- return null;
- //其余与父类实现一样
- else if (activeReaders_ == 0 && waitingWriters_ > 0)
- return writerLock_;
- else
- return null;
- }
- }
protected boolean allowReader() {
//与父类的变化在于,activeWriter_ == Thread.currentThread(),
//也就是说当本线程已经获得写控制的时候,返回true
return (activeWriter_ == null && waitingWriters_ == 0) ||
activeWriter_ == Thread.currentThread();
}
protected synchronized boolean startRead() {
Thread t = Thread.currentThread();
//查看本线程是否已经获得读控制
Object c = readers_.get(t);
if (c != null) { // already held -- just increment hold count
//计数+1
readers_.put(t, new Integer(((Integer)(c)).intValue()+1));
++activeReaders_;
return true;
}
//调用allowReader
else if (allowReader()) {
//将本线程获锁次数纪录在readers_这个map里
readers_.put(t, IONE);
++activeReaders_;
return true;
}
else
return false;
}
protected synchronized Signaller endRead() {
Thread t = Thread.currentThread();
Object c = readers_.get(t);
if (c == null)
throw new IllegalStateException();
--activeReaders_;
if (c != IONE) { // 多于一个读线程有控制权,more than one hold; 计数递减
int h = ((Integer)(c)).intValue()-1;
Integer ih = (h == 1)? IONE : new Integer(h);
readers_.put(t, ih);
return null;
}
else {
readers_.remove(t);
if (writeHolds_ > 0) // 本线程还有写锁在占用控制权
return null;
//其余与父类实现一样
else if (activeReaders_ == 0 && waitingWriters_ > 0)
return writerLock_;
else
return null;
}
}
Reader部分相对于父类的变化在于
* 每个reader试图竞争控制权时,都会将本线程句柄与activeWriter进行比较,相同则认为是可以重入。
* 每个reader线程都在readers_的map里有一个计数器,判断当前有多少次获得reader锁权,释放的时候,只有当计数器为0时才通知其他写线程结束wait。
接着看看Writer部分的重写函数
- protected synchronized boolean startWrite() {
- if (activeWriter_ == Thread.currentThread()) { // 反复重入
- ++writeHolds_;
- return true;
- }
- else if (writeHolds_ == 0) {
- //如果没有人在读(activeReaders_==0)和,或者在读的线程和本线程一样,并且readers里没有其他线程
- if (activeReaders_ == 0 ||
- (readers_.size() == 1 &&
- readers_.get(Thread.currentThread()) != null)) {
- //如果本线程在读中,则也可以进入writeLock
- activeWriter_ = Thread.currentThread();
- writeHolds_ = 1;
- return true;
- }
- else
- return false;
- }
- else
- return false;
- }
- protected synchronized Signaller endWrite() {
- --writeHolds_;
- if (writeHolds_ > 0)
- //这是主要与父类不一样的地方,写锁计数标示仍然有写锁没有被释放
- return null;
- else {
- //与父类一致
- activeWriter_ = null;
- if (waitingReaders_ > 0 && allowReader())
- return readerLock_;
- else if (waitingWriters_ > 0)
- return writerLock_;
- else
- return null;
- }
- }
protected synchronized boolean startWrite() {
if (activeWriter_ == Thread.currentThread()) { // 反复重入
++writeHolds_;
return true;
}
else if (writeHolds_ == 0) {
//如果没有人在读(activeReaders_==0)和,或者在读的线程和本线程一样,并且readers里没有其他线程
if (activeReaders_ == 0 ||
(readers_.size() == 1 &&
readers_.get(Thread.currentThread()) != null)) {
//如果本线程在读中,则也可以进入writeLock
activeWriter_ = Thread.currentThread();
writeHolds_ = 1;
return true;
}
else
return false;
}
else
return false;
}
protected synchronized Signaller endWrite() {
--writeHolds_;
if (writeHolds_ > 0)
//这是主要与父类不一样的地方,写锁计数标示仍然有写锁没有被释放
return null;
else {
//与父类一致
activeWriter_ = null;
if (waitingReaders_ > 0 && allowReader())
return readerLock_;
else if (waitingWriters_ > 0)
return writerLock_;
else
return null;
}
}
Writer主要与父类不同的地方是
* 通过writeHolds来记录本线程获得锁的次数,以便在release时正确调用通知机制
* 通过当前线程和activeWriter线程比较来实现重入
1.3 EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock
ReaderPreferenceReadWriteLock类和父类唯一不同就是allowReader方法
- protected boolean allowReader() {
- //只要没有写,就允许读
- return activeWriter_ == null;
- }
protected boolean allowReader() {
//只要没有写,就允许读
return activeWriter_ == null;
}
这个类在大多数场景下都不太实用,多数人主要还是使用writer优先锁。