ReentrantLock(可重入锁)

基于AQS实现的可重入锁,包括公平和非公平两种实现方式。

公平与非公平的差异:

1、非公平:主动抢锁,抢锁失败,进入AQS实现的获取锁流程(排队去)

2、公平锁:不主动抢锁,直接进入AQS的获取锁方法(排队去),这也是公平与非公平锁(主动尝试抢锁)的区别

可重入主要体现在对同一线程访问资源时,对资源state的值叠加

public class ReentrantLock implements Lock, java.io.Serializable {

    //提供所有实现机制的同步器
    private final Sync sync;

    /**
     * 继承至AQS的同步器基础类,子类分公平和非公平实现。用AQS的state表示获取锁资源的数量
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        //获取锁的抽象方法,由子类具体实现
        abstract void lock();

        //非公平锁获取锁的方法
        final boolean nonfairTryAcquire(int acquires) {
            //获取当前线程
            final Thread current = Thread.currentThread();
            //获取AQS的state值
            int c = getState();
            //尝试获取锁
            if (c == 0) {
                //cas继续尝试获取
                if (compareAndSetState(0, acquires)) {
                    //获取成功,设置获取到互斥锁的当前线程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //如果没有锁资源,则判断当前锁线程是否就是自己,如果是则进入方法,这块是可重入思想的主要实现
            else if (current == getExclusiveOwnerThread()) { 
                //注意:这里分支块为啥没有CAS呢?因为进入这个方法时,当前线程算是重入,这就证明已经是加过互斥锁的,不存在竞争问题
                //用AQS的state记录可重入次数
                int nextc = c + acquires;
                if (nextc < 0) // 超出int范围,超出会变成负数
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);  //设置AQS state值
                return true;
            }
            return false;
        }

        //释放锁资源的方法(不区分公平与非公平方式)
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;  //用原state减去释放的资源值
            if (Thread.currentThread() != getExclusiveOwnerThread()) 
                //当前释放资源的线程并不是获取锁的线程,抛出异常
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {  //完全释放成功,其他线程可以获取锁了
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);  //更新state值
            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;
        }

        /**
         * Reconstitutes the instance from a stream (that is, deserializes it).
         */
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }
    }

    //实现非公平锁的同步器
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        //获取锁方法
        final void lock() {
            //CAS设置state值,意为抢锁
            if (compareAndSetState(0, 1))  
                //抢锁成功,设置互斥锁拥有线程为当前线程
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1); //抢锁失败,进入AQS实现的获取锁流程
        }

        protected final boolean tryAcquire(int acquires) {
            //调用父类提供的非公平锁获取方法
            return nonfairTryAcquire(acquires);
        }
    }

    //实现公平锁的同步器
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            //不主动抢锁,直接进入AQS的获取锁方法,这也是公平与非公平锁(主动尝试抢锁)的区别
            acquire(1);
        }

        //获取锁的实现,给AQS调用的勾子函数的子类实现方法
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                //没有其他线程上锁,CAS抢锁
                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 ReentrantLock() {
        sync = new NonfairSync();
    }
	//根据fair来创建公平和非公平锁同步器
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
	//锁操作,调用sync同步器lock方法
    public void lock() {
        sync.lock();
    }

    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    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);
    }

    //获取AQS条件对象
    public Condition newCondition() {
        return sync.newCondition();
    }
}

你可能感兴趣的:(JAVA并发编程,JUC包,java,开发语言)