ReentrantReadWriteLock

来源:互联网 发布:足球数据库 编辑:程序博客网 时间:2024/04/30 12:27
//可重入读写锁public class ReentrantReadWriteLock        implements ReadWriteLock, java.io.Serializable {    private static final long serialVersionUID = -6992448646407690164L;    private final ReentrantReadWriteLock.ReadLock readerLock;    private final ReentrantReadWriteLock.WriteLock writerLock;    final Sync sync;    public ReentrantReadWriteLock() {        this(false);    }    public ReentrantReadWriteLock(boolean fair) {        sync = fair ? new FairSync() : new NonfairSync();        readerLock = new ReadLock(this);        writerLock = new WriteLock(this);    }    public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; }    public ReentrantReadWriteLock.ReadLock  readLock()  { return readerLock; }    abstract static class Sync extends AbstractQueuedSynchronizer {        private static final long serialVersionUID = 6317671515068378041L;        // 高16位为读锁,低16位为写锁        static final int SHARED_SHIFT   = 16;        //读锁单元        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);        //读写锁最大值        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;        /** Returns the number of shared holds represented in count  */        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }        /** Returns the number of exclusive holds represented in count  */        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }        //每个读线程重入次数,计数器        static final class HoldCounter {            int count = 0;            final long tid = getThreadId(Thread.currentThread());        }        static final class ThreadLocalHoldCounter            extends ThreadLocal<HoldCounter> {            public HoldCounter initialValue() {                return new HoldCounter();            }        }        private transient ThreadLocalHoldCounter readHolds;        //最近一次成功获取读锁的读线程,计数器        private transient HoldCounter cachedHoldCounter;        //第一个读线程        private transient Thread firstReader = null;        //第一个读线程计数        private transient int firstReaderHoldCount;        Sync() {            readHolds = new ThreadLocalHoldCounter();            setState(getState()); // ensures visibility of readHolds        }        abstract boolean readerShouldBlock();        abstract boolean writerShouldBlock();        //独占模式下释放锁        protected final boolean tryRelease(int releases) {            if (!isHeldExclusively())                throw new IllegalMonitorStateException();            int nextc = getState() - releases;            boolean free = exclusiveCount(nextc) == 0;            if (free)//写锁为0                setExclusiveOwnerThread(null);            setState(nextc);            return free;        }        //独占模式下获取锁        protected final boolean tryAcquire(int acquires) {            Thread current = Thread.currentThread();            int c = getState();//获取状态            int w = exclusiveCount(c);//写线程数量            if (c != 0) {//状态不为0                // (Note: if c != 0 and w == 0 then shared count != 0)                //写线程数量为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;            }            if (writerShouldBlock() ||                !compareAndSetState(c, c + acquires))//写线程是否应该被阻塞                return false;            setExclusiveOwnerThread(current);//成功获得锁,设置当前线程为锁独占者            return true;        }        protected final boolean tryReleaseShared(int unused) {            Thread current = Thread.currentThread();            if (firstReader == current) { //当前线程为第一个读线程                // assert firstReaderHoldCount > 0;                if (firstReaderHoldCount == 1) //读线程获取锁一次                    firstReader = null;                else                    firstReaderHoldCount--;            } else { //当前线程不是第一个读线程                HoldCounter rh = cachedHoldCounter;                // 计数器为空或者计数器的tid不为当前正在运行的线程的tid                if (rh == null || rh.tid != getThreadId(current))                    rh = readHolds.get();// 获取当前线程对应的计数器                int count = rh.count;                if (count <= 1) {// 计数小于等于1                    readHolds.remove();//删除计数器                    if (count <= 0)                        throw unmatchedUnlockException();                }                --rh.count;//重入次数减1            }            for (;;) {                int c = getState();                int nextc = c - SHARED_UNIT;                if (compareAndSetState(c, nextc))                    return nextc == 0;            }        }        private IllegalMonitorStateException unmatchedUnlockException() {            return new IllegalMonitorStateException(                "attempt to unlock read lock, not locked by current thread");        }        //共享模式下获取锁        protected final int tryAcquireShared(int unused) {            Thread current = Thread.currentThread();            int c = getState();            //写锁数量不为0且当前线程不是独占者            if (exclusiveCount(c) != 0 &&                getExclusiveOwnerThread() != current)                return -1;            int r = sharedCount(c);//读锁数量            if (!readerShouldBlock() &&                r < MAX_COUNT &&                compareAndSetState(c, c + SHARED_UNIT)) {                if (r == 0) {//读线程为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);        }        final int fullTryAcquireShared(Thread current) {            HoldCounter rh = null;            for (;;) {                int c = getState();                if (exclusiveCount(c) != 0) {                    if (getExclusiveOwnerThread() != current)                        return -1;                    // else we hold the exclusive lock; blocking here                    // would cause deadlock.                } else if (readerShouldBlock()) {                    // Make sure we're not acquiring read lock reentrantly                    if (firstReader == current) {                        // assert firstReaderHoldCount > 0;                    } else {                        if (rh == null) {                            rh = cachedHoldCounter;                            if (rh == null || rh.tid != getThreadId(current)) {                                rh = readHolds.get();                                if (rh.count == 0)                                    readHolds.remove();                            }                        }                        if (rh.count == 0)                            return -1;                    }                }                if (sharedCount(c) == MAX_COUNT)                    throw new Error("Maximum lock count exceeded");                if (compareAndSetState(c, c + SHARED_UNIT)) {                    if (sharedCount(c) == 0) {                        firstReader = current;                        firstReaderHoldCount = 1;                    } else if (firstReader == current) {                        firstReaderHoldCount++;                    } else {                        if (rh == null)                            rh = cachedHoldCounter;                        if (rh == null || rh.tid != getThreadId(current))                            rh = readHolds.get();                        else if (rh.count == 0)                            readHolds.set(rh);                        rh.count++;                        cachedHoldCounter = rh; // cache for release                    }                    return 1;                }            }        }        final boolean tryWriteLock() {            Thread current = Thread.currentThread();            int c = getState();            if (c != 0) {                int w = exclusiveCount(c);                if (w == 0 || current != getExclusiveOwnerThread())                    return false;                if (w == MAX_COUNT)                    throw new Error("Maximum lock count exceeded");            }            if (!compareAndSetState(c, c + 1))                return false;            setExclusiveOwnerThread(current);            return true;        }        final boolean tryReadLock() {            Thread current = Thread.currentThread();            for (;;) {                int c = getState();                if (exclusiveCount(c) != 0 &&                    getExclusiveOwnerThread() != current)                    return false;                int r = sharedCount(c);                if (r == MAX_COUNT)                    throw new Error("Maximum lock count exceeded");                if (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 true;                }            }        }        protected final boolean isHeldExclusively() {            return getExclusiveOwnerThread() == Thread.currentThread();        }        final ConditionObject newCondition() {            return new ConditionObject();        }        final Thread getOwner() {            return ((exclusiveCount(getState()) == 0) ?                    null :                    getExclusiveOwnerThread());        }        final int getReadLockCount() {            return sharedCount(getState());        }        final boolean isWriteLocked() {            return exclusiveCount(getState()) != 0;        }        final int getWriteHoldCount() {            return isHeldExclusively() ? exclusiveCount(getState()) : 0;        }        final int getReadHoldCount() {            if (getReadLockCount() == 0)                return 0;            Thread current = Thread.currentThread();            if (firstReader == current)                return firstReaderHoldCount;            HoldCounter rh = cachedHoldCounter;            if (rh != null && rh.tid == getThreadId(current))                return rh.count;            int count = readHolds.get().count;            if (count == 0) readHolds.remove();            return count;        }        private void readObject(java.io.ObjectInputStream s)            throws java.io.IOException, ClassNotFoundException {            s.defaultReadObject();            readHolds = new ThreadLocalHoldCounter();            setState(0); // reset to unlocked state        }        final int getCount() { return getState(); }    }    static final class NonfairSync extends Sync {        private static final long serialVersionUID = -8159625535654395037L;        final boolean writerShouldBlock() {            return false; // writers can always barge        }        final boolean readerShouldBlock() {            return apparentlyFirstQueuedIsExclusive();        }    }    static final class FairSync extends Sync {        private static final long serialVersionUID = -2274990926593161451L;        final boolean writerShouldBlock() {            return hasQueuedPredecessors();        }        final boolean readerShouldBlock() {            return hasQueuedPredecessors();        }    }    public static class ReadLock implements Lock, java.io.Serializable {        private static final long serialVersionUID = -5992448646407690164L;        private final Sync sync;        protected ReadLock(ReentrantReadWriteLock lock) {            sync = lock.sync;        }        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();        }        public String toString() {            int r = sync.getReadLockCount();            return super.toString() +                "[Read locks = " + r + "]";        }    }    public static class WriteLock implements Lock, java.io.Serializable {        private static final long serialVersionUID = -4992448646407690164L;        private final Sync sync;        protected WriteLock(ReentrantReadWriteLock lock) {            sync = lock.sync;        }        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 String toString() {            Thread o = sync.getOwner();            return super.toString() + ((o == null) ?                                       "[Unlocked]" :                                       "[Locked by thread " + o.getName() + "]");        }        public boolean isHeldByCurrentThread() {            return sync.isHeldExclusively();        }        public int getHoldCount() {            return sync.getWriteHoldCount();        }    }}
0 0
原创粉丝点击