• ReentrantLock源码


    public class ReentrantLock1 implements Lock, java.io.Serializable {
        private static final long serialVersionUID = 7373984872572414699L;
        //创建一个ReentrantLock1里面有一个sync,里面有一个state和队列。
        //多个线程竞争ReentrantLock的sync对象的state和owenerThread属性,修改一瞬间cas。
        private final Sync sync;
    
        abstract static class Sync extends AbstractQueuedSynchronizer1 {
            private static final long serialVersionUID = -5179523762034025860L;
    
            abstract void lock();
    
            final boolean nonfairTryAcquire(int acquires) {//非公片的tryAcquire(1)
                final Thread current = Thread.currentThread();
                int c = getState();//state=1表示sync对象里面有线程 
                if (c == 0) {//没有人占有锁,不在队列线程和队列第一个线程开始抢锁。
                    if (compareAndSetState(0, acquires)) {//又获取一次,只有修改共享变量cas,并且相当于代码加锁。
                        setExclusiveOwnerThread(current);
                        return true;
                    }//获取失败返回false
                }
                //可重入的lock
                else if (current == getExclusiveOwnerThread()) {
                    //单线程进来。不可能执行期间别的线程进来,因为要进来必须要之前的线程退出,在执行里面代码时候,当前线程不会退出(没有调用unlock)。相当于加锁。
                    int nextc = c + acquires;
                    if (nextc < 0) // overflow
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);//单线程操作不用cas,
                    return true;
                }
                return false;
            }
    
            protected final boolean tryRelease(int releases) {
                //不可能2个线程去unlock,因为只有一个线程进来lock然后unlock,另一个线程在lock在unlock。
                int c = getState() - releases;
                if (Thread.currentThread() != getExclusiveOwnerThread())//此时不是他拥有锁,在排队,不能释放锁
                    throw new IllegalMonitorStateException();
                boolean free = false;
                if (c == 0) {//C!=0,是不会设置OwnerThread=null的。
                    free = true;
                    setExclusiveOwnerThread(null);
                }
                setState(c);//setState(0),一定要是0。不在队列的线程可以抢锁队列第一个节点(没有阻塞)可以抢锁,head还没有去唤醒。
                return free;
            }
    
            protected final boolean isHeldExclusively() {
                return getExclusiveOwnerThread() == Thread.currentThread();
            }
    
            final ConditionObject newCondition() {
                return new ConditionObject();
            }
    
            final Thread getOwner() {
                return getState() == 0 ? null : getExclusiveOwnerThread();
            }
    
            final int getHoldCount() {
                return isHeldExclusively() ? getState() : 0;
            }
    
            final boolean isLocked() {
                return getState() != 0;
            }
        }
    
        static final class NonfairSync extends Sync {
            private static final long serialVersionUID = 7316153563782823691L;
    
            final void lock() {
                //这也是非公平的体现,因为新来的线程没有马上加入队列尾部,而是先尝试抢占同步状态。
                if (compareAndSetState(0, 1))//sync的state=1属性,设置成功就获取这把锁lock方法正常返回,
                    setExclusiveOwnerThread(Thread.currentThread());//设置sync的exclusiveOwnerThread属性=这个线程,完事退出。
                else
                    try {
                        acquire(1);//没有获取sync这把锁。入队
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            }
    
            protected final boolean tryAcquire(int acquires) {//1
                return nonfairTryAcquire(acquires);
            }
        }
    
        //公平锁
        static final class FairSync extends Sync {
            private static final long serialVersionUID = -3000897897090466540L;
    
            final void lock() {//不会一来就尝试获取锁,因为是公平的。
                try {
                    acquire(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            //tryAcquire的公平版本。除非递归调用或没有等待线程或是第一个,否则不要授予访问权限。
            protected final boolean tryAcquire(int acquires) {
                final Thread current = Thread.currentThread();
                int c = getState();
                //释放锁是先设置owenerThread=null在设置state=0,有可能owenerThread=null了state还不等于0,就去排队。
                if (c == 0) {
                    //队列空获取锁,当前线程是第一个获取锁。队列不空但是当前线程不是第一个(排队)不去获取锁。就公平。
                    if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
                        setExclusiveOwnerThread(current);
                        return true;
                    }
                }
                else if (current == getExclusiveOwnerThread()) {
                    int nextc = c + acquires;
                    if (nextc < 0)
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);
                    return true;
                }
                return false;
            }
        }
    
        //非公平锁
        public ReentrantLock1() {
            sync = new NonfairSync();
        }
    
        public ReentrantLock1(boolean fair) {
            sync = fair ? new FairSync() : new NonfairSync();
        }
    
        public void lock() {
            sync.lock(); 
        }
        
        // 获取锁,若当前锁不可用(被其他线程获取); 则阻塞线程,等待获取锁,则这个线程能够响应中断,即中断线程的等待状态
        public void lockInterruptibly() throws InterruptedException {
            sync.acquireInterruptibly(1);
        }
    
        // 来尝试获取锁,如果获取成功,则返回true; 如果获取失败(即锁已被其他线程获取),则返回false
        // 也就是说,这个方法无论如何都会立即返回。不去排队。
        public boolean tryLock() {
            return sync.nonfairTryAcquire(1);
        }
    
        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();
        }
    
        /* 
        查询当前线程对此锁的保留数。
    
        线程对每个与解锁操作不匹配的锁定操作都具有对锁的保留
         
        保留计数信息通常仅用于测试和调试目的。例如,如果不应该在已经持有锁的情况下输入某段代码,那么我们可以断言这一事实:
          class X {
            ReentrantLock lock = new ReentrantLock();
             // ...
             public void m() {
               assert lock.getHoldCount() == 0;
               lock.lock();
               try {
                 // ... method body
               } finally {
                 lock.unlock();
               }
             }
           }}</pre>
        当前线程持有此锁的次数,如果当前线程不持有此锁,则为零。
         */
        public int getHoldCount() {
            return sync.getHoldCount();
        }
    
        /* 
        查询当前线程是否持有此锁,
        例如,只有在持有锁时才应调用的方法可以断言情况如下:
          
           class X {
             ReentrantLock lock = new ReentrantLock();
             public void m() {
                 assert lock.isHeldByCurrentThread();
                 // ...  
             }
           }} 
          
        它还可用于确保以不可重入的方式使用可重入锁,例如:
    
           class X {
             ReentrantLock lock = new ReentrantLock();
             // ...
             public void m() {
                 assert !lock.isHeldByCurrentThread();
                 lock.lock();
                 try {
                     // ... method body
                 } finally {
                     lock.unlock();
                 }
             }
           }} 
         */
        public boolean isHeldByCurrentThread() {
            return sync.isHeldExclusively();
        }
    
        public boolean isLocked() {
            return sync.isLocked();
        }
    
        public final boolean isFair() {
            return sync instanceof FairSync;
        }
    
        protected Thread getOwner() {
            return sync.getOwner();
        }
    
        public final boolean hasQueuedThreads() {
            return sync.hasQueuedThreads();
        }
    
        public final boolean hasQueuedThread(Thread thread) {
            return sync.isQueued(thread);
        }
    
        public final int getQueueLength() {
            return sync.getQueueLength();
        }
    
        protected Collection<Thread> getQueuedThreads() {
            return sync.getQueuedThreads();
        }
    
        public boolean hasWaiters(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.hasWaiters((AbstractQueuedSynchronizer1.ConditionObject)condition);
        }
    
        public int getWaitQueueLength(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitQueueLength((AbstractQueuedSynchronizer1.ConditionObject)condition);
        }
    
        protected Collection<Thread> getWaitingThreads(Condition condition) {
            if (condition == null)
                throw new NullPointerException();
            if (!(condition instanceof AbstractQueuedSynchronizer1.ConditionObject))
                throw new IllegalArgumentException("not owner");
            return sync.getWaitingThreads((AbstractQueuedSynchronizer1.ConditionObject)condition);
        }
    
        public String toString() {
            Thread o = sync.getOwner();
            return super.toString() + ((o == null) ? "[Unlocked]" :  "[Locked by thread " + o.getName() + "]");
        }
    }
  • 相关阅读:
    理解javascript作用域及hosting机制
    angular分页指令
    python 设计模式之门面模式
    代码Rework中的反思
    python 设计模式之观察者模式
    python 设计模式之命令模式
    Django性能调优
    python 设计模式之MVC模式
    httperf+autobench测试web应用
    对工作的感悟
  • 原文地址:https://www.cnblogs.com/yaowen/p/11355089.html
Copyright © 2020-2023  润新知