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() + "]");
    }
}

 

posted @ 2019-08-14 22:21  无天666  阅读(142)  评论(0编辑  收藏  举报