⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reentrantreadwritelock.java

📁 java1.6众多例子参考
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
             *    and set owner.             */            Thread current = Thread.currentThread();            int c = getState();            int w = exclusiveCount(c);            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");            }            if ((w == 0 && writerShouldBlock(current)) ||                !compareAndSetState(c, c + acquires))                return false;            setExclusiveOwnerThread(current);            return true;        }        protected final boolean tryReleaseShared(int unused) {            HoldCounter rh = cachedHoldCounter;            Thread current = Thread.currentThread();            if (rh == null || rh.tid != current.getId())                rh = readHolds.get();            if (rh.tryDecrement() <= 0)                throw new IllegalMonitorStateException();            for (;;) {                int c = getState();                int nextc = c - SHARED_UNIT;                if (compareAndSetState(c, nextc))                    return nextc == 0;            }        }        protected final int tryAcquireShared(int unused) {            /*             * Walkthrough:             * 1. If write lock held by another thread, fail             * 2. If count saturated, throw error             * 3. 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.             * 4. If step 3 fails either because thread             *    apparently not eligible or CAS fails,             *    chain to version with full retry loop.             */            Thread current = Thread.currentThread();            int c = getState();            if (exclusiveCount(c) != 0 &&                getExclusiveOwnerThread() != current)                return -1;            if (sharedCount(c) == MAX_COUNT)                throw new Error("Maximum lock count exceeded");            if (!readerShouldBlock(current) &&                compareAndSetState(c, c + SHARED_UNIT)) {                HoldCounter rh = cachedHoldCounter;                if (rh == null || rh.tid != current.getId())                    cachedHoldCounter = rh = readHolds.get();                rh.count++;                return 1;            }            return fullTryAcquireShared(current);        }        /**         * Full version of acquire for reads, that handles CAS misses         * and reentrant reads not dealt with in tryAcquireShared.         */        final int fullTryAcquireShared(Thread current) {            /*             * This code is in part redundant with that in             * tryAcquireShared but is simpler overall by not             * complicating tryAcquireShared with interactions between             * retries and lazily reading hold counts.             */            HoldCounter rh = cachedHoldCounter;            if (rh == null || rh.tid != current.getId())                rh = readHolds.get();            for (;;) {                int c = getState();                int w = exclusiveCount(c);                if ((w != 0 && getExclusiveOwnerThread() != current) ||                    ((rh.count | w) == 0 && readerShouldBlock(current)))                    return -1;                if (sharedCount(c) == MAX_COUNT)                    throw new Error("Maximum lock count exceeded");                if (compareAndSetState(c, c + SHARED_UNIT)) {                    cachedHoldCounter = rh; // cache for release                    rh.count++;                    return 1;                }            }        }        /**         * Performs tryLock for write, enabling barging in both modes.         * This is identical in effect to tryAcquire except for lack         * of calls to writerShouldBlock         */        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;        }        /**         * Performs tryLock for read, enabling barging in both modes.         * This is identical in effect to tryAcquireShared except for         * lack of calls to readerShouldBlock         */        final boolean tryReadLock() {            Thread current = Thread.currentThread();            for (;;) {                int c = getState();                if (exclusiveCount(c) != 0 &&                    getExclusiveOwnerThread() != current)                    return false;                if (sharedCount(c) == MAX_COUNT)                    throw new Error("Maximum lock count exceeded");                if (compareAndSetState(c, c + SHARED_UNIT)) {                    HoldCounter rh = cachedHoldCounter;                    if (rh == null || rh.tid != current.getId())                        cachedHoldCounter = rh = readHolds.get();                    rh.count++;                    return true;                }            }        }        protected final boolean isHeldExclusively() {            // While we must in general read state before owner,            // we don't need to do so to check if current thread is owner            return getExclusiveOwnerThread() == Thread.currentThread();        }        // Methods relayed to outer class        final ConditionObject newCondition() {            return new ConditionObject();        }        final Thread getOwner() {            // Must read state before owner to ensure memory consistency            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() {            return getReadLockCount() == 0? 0 : readHolds.get().count;        }        /**         * Reconstitute this lock instance from a stream         * @param s the stream         */        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(); }    }    /**     * Nonfair version of Sync     */    final static class NonfairSync extends Sync {        private static final long serialVersionUID = -8159625535654395037L;        final boolean writerShouldBlock(Thread current) {            return false; // writers can always barge        }        final boolean readerShouldBlock(Thread current) {            /* As a heuristic to avoid indefinite writer starvation,             * block if the thread that momentarily appears to be head             * of queue, if one exists, is a waiting writer. This is             * only a probablistic effect since a new reader will not             * block if there is a waiting writer behind other enabled             * readers that have not yet drained from the queue.             */            return apparentlyFirstQueuedIsExclusive();        }    }    /**     * Fair version of Sync     */    final static class FairSync extends Sync {        private static final long serialVersionUID = -2274990926593161451L;        final boolean writerShouldBlock(Thread current) {            // only proceed if queue is empty or current thread at head            return !isFirst(current);        }        final boolean readerShouldBlock(Thread current) {            // only proceed if queue is empty or current thread at head            return !isFirst(current);        }    }    /**     * The lock returned by method {@link ReentrantReadWriteLock#readLock}.     */    public static class ReadLock implements Lock, java.io.Serializable  {        private static final long serialVersionUID = -5992448646407690164L;        private final Sync sync;        /**         * Constructor for use by subclasses         *         * @param lock the outer lock object         * @throws NullPointerException if the lock is null         */        protected ReadLock(ReentrantReadWriteLock lock) {            sync = lock.sync;        }        /**         * Acquires the read lock.         *         * <p>Acquires the read lock if the write lock is not held by         * another thread and returns immediately.         *         * <p>If the write lock is held by another thread then         * the current thread becomes disabled for thread scheduling         * purposes and lies dormant until the read lock has been acquired.         */        public void lock() {            sync.acquireShared(1);        }        /**         * Acquires the read lock unless the current thread is         * {@linkplain Thread#interrupt interrupted}.         *         * <p>Acquires the read lock if the write lock is not held         * by another thread and returns immediately.         *         * <p>If the write lock is held by another thread then the         * current thread becomes disabled for thread scheduling         * purposes and lies dormant until one of two things happens:         *         * <ul>         *         * <li>The read lock is acquired by the current thread; or         *         * <li>Some other thread {@linkplain Thread#interrupt interrupts}         * the current thread.         *         * </ul>         *         * <p>If the current thread:         *         * <ul>         *         * <li>has its interrupted status set on entry to this method; or         *         * <li>is {@linkplain Thread#interrupt interrupted} while         * acquiring the read lock,         *         * </ul>         *         * then {@link InterruptedException} is thrown and the current         * thread's interrupted status is cleared.         *         * <p>In this implementation, as this method is an explicit         * interruption point, preference is given to responding to         * the interrupt over normal or reentrant acquisition of the         * lock.         *         * @throws InterruptedException if the current thread is interrupted         */        public void lockInterruptibly() throws InterruptedException {            sync.acquireSharedInterruptibly(1);        }        /**         * Acquires the read lock only if the write lock is not held by         * another thread at the time of invocation.         *         * <p>Acquires the read lock if the write lock is not held by         * another thread and returns immediately with the value         * {@code true}. Even when this lock has been set to use a         * fair ordering policy, a call to {@code tryLock()}         * <em>will</em> immediately acquire the read lock if it is         * available, whether or not other threads are currently         * waiting for the read lock.  This &quot;barging&quot; behavior         * can be useful in certain circumstances, even though it         * breaks fairness. If you want to honor the fairness setting         * for this lock, then use {@link #tryLock(long, TimeUnit)         * tryLock(0, TimeUnit.SECONDS) } which is almost equivalent         * (it also detects interruption).         *         * <p>If the write lock is held by another thread then         * this method will return immediately with the value         * {@code false}.         *         * @return {@code true} if the read lock was acquired         */        public  boolean tryLock() {            return sync.tryReadLock();        }        /**         * Acquires the read lock if the write lock is not held by         * another thread within the given waiting time and the         * current thread has not been {@linkplain Thread#interrupt         * interrupted}.         *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -