首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java的ReadWriteLock兑现机制解析(2)

2012-12-23 
Java的ReadWriteLock实现机制解析(2)1.3 EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceRea

Java的ReadWriteLock实现机制解析(2)

1.3 EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock

????? 上一篇说到了WriterPreferenceReadWriteLock,这一篇说一下ReentrantWriterPreferenceReadWriteLock。??

????? 顾名思义,该类实现的是可重入的的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);

?

?? 再来看看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;    }}

?

??? 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;    }}

?

?? Writer主要与父类不同的地方是

?? * 通过writeHolds来记录本线程获得锁的次数,以便在release时正确调用通知机制

?? * 通过当前线程和activeWriter线程比较来实现重入

?

1.3 EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock

?

? ReaderPreferenceReadWriteLock类和父类唯一不同就是allowReader方法

protected boolean allowReader() {    //只要没有写,就允许读    return activeWriter_ == null;}

?? 这个类在大多数场景下都不太实用,多数人主要还是使用writer优先锁。

热点排行