ReentrantReadWriteLock

外部类Sync简介:

后面看过AQS咱们都晓得,AQS中应用一个int型变量来示意锁的持有数,然而对于ReentrantReadWriteLock来说,它是分读锁和写锁,那么如何示意这两种锁的持有数呢?读写锁中采纳的形式就是将int型一分为二,高16位,所有线程持有的读锁数,低16位用来示意写锁的持有个数;
读锁是一个共享锁,高16位示意的是所有线程总的持读锁数,那如何获取以后线程重入读锁数呢?这里天然引入了ThreadLocal来保留每个线程重入读锁的计数。
        static final int SHARED_SHIFT   = 16;//用于计数出高161位的偏移值(读锁)        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);//65536        //最大持锁个数        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; //用于计数出state的低16位的掩码        //该办法获取int变量高16位,即读锁持有计数        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }        //该办法获取int变量低16位,即写锁持有计数        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }        // HoldCounter变量用于存储每个线程id以及对应的读锁持有计数        static final class HoldCounter {            int count = 0;            // 应用线程id而不是线程援用,是为了避免残留            // 这里可能是思考到强援用,垃圾对象无奈回收,导致内存泄露            final long tid = getThreadId(Thread.currentThread());        }        // 以后线程持有的读锁计数,ThreadLocalHoldCounter其实就是一个ThreadLocal<HoldCounter>        private transient ThreadLocalHoldCounter readHolds;        //上面三个变量是用的比拟多的变量,为了进步获取效率,就独自缓存了        // 保留上个申请读锁线程的HoldCounter。        private transient HoldCounter cachedHoldCounter;        // 保留第一个获取到读锁的线程        private transient Thread firstReader = null;        // 保留第一个获取到读锁的线程持有的读锁计数        private transient int firstReaderHoldCount;