对ReentrantLock源码的解读_JDK8

ReentrantLock

源码基于JDK8中的rt.jar下的java.util.concurrent.locks.ReentrantLock
此前写过一篇基于JDK14的,两份源码大致是一样的,只有个别方法有区别,而且仅仅是方法的名称有区别,实现的方式和具体的思想大致一样
对ReentrantLock源码的解读_JDK14


方法结构图

在这里插入图片描述


源码分析

package com.ramscy;

import java.util.Collection;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;

    private final Sync sync;

    /**
     * 继承自AQS的抽象静态内部类Sync
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        abstract void lock();

        /**
         * 获取当前线程对象,并尝试上锁
         * 如果state状态值为0,则可以直接通过CAS操作上锁
         * 如果state不为0,说明已经有线程持有锁
         * 则需判断持有锁的线程是否是当前线程,如果是,则state值加1,否则尝试上锁失败
         *
         * @return
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (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;
        }

        /**
         * 尝试释放锁
         * 如果当前线程是持有锁的线程,
         * 且上锁次数和当前获得的state值(当前上锁次数)相同时,则可以成功释放锁
         * ( 因为可能存在一种可能,传入的releases参数,在调用tryRelease方法时变化了,即同一个线程又获得了锁,
         * state值增加了 )
         * 否则,则释放掉releases层锁,设置state值为c = getState() - releases;
         * 并返回false,释放锁失败
         * @param releases
         * @return
         */
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

        /**
         * 判断当前线程是否是持有锁的线程
         * @return
         */
        protected final boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }

        /**
         * 获取ConditionObject对象,ConditionObject继承自Condition
         * @return
         */
        final ConditionObject newCondition() {
            return new ConditionObject();
        }

        /**
         * 获取当前持有锁的线程
         * @return
         */
        final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }

        /**
         * 如果当前线程是持有锁的线程,则获取当前可重入锁的state值,即上锁次数
         * @return
         */
        final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
        }

        /**
         * 判断是否上锁,state值是否为0,为0则未上锁
         * @return
         */
        final boolean isLocked() {
            return getState() != 0;
        }

        /**
         * 设置state值为0,即无锁状态
         * @param s
         * @throws java.io.IOException
         * @throws ClassNotFoundException
         */
        private void readObject(java.io.ObjectInputStream s)
                throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0);
        }
    }

    /**
     * 非公平锁
     */
    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * 重写了Sync父类的抽象方法lock()
         * 与公平锁不同的是,这里先进行一次cas操作,如果成功,则直接设置当前线程为持有锁的线程
         * 否则,在尝试获取锁
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        /**
         * 直接调用父类的方法
         * @param acquires
         * @return
         */
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

    /**
     * 公平锁
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        /**
         * 重写了父类的抽象方法lock(),尝试获取锁
         */
        final void lock() {
            acquire(1);
        }

        /**
         * FairSync --> Sync --> AbstractQueuedSynchronizer
         * 重写了AbstractQueuedSynchronizer父类的tryAcquire方法
         * 尝试抢占锁
         * @param acquires
         * @return
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                /**
                 * 与父类非公平锁实现的方法不同的地方,就是hasQueuedThreads方法
                 * 这个方法返回队列中是否有等待的线程,如果有则返回true
                 * 在这里的意思是,如果有等待的线程,返回true并取反,if条件无法执行
                 * 也即,无法让后来的线程插队,current就无法在正在队列中等待的线程之前获得锁
                 */
                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;
        }
    }

    /**
     * 空参构造方法
     * 为抽象静态内部类Sync默认创建一个非公平锁对象
     */
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * 有参构造方法
     * 若传入参数为true,则为抽象静态内部类Sync创建一个公平锁对象
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

    /**
     * ReentrantLock对象的lock接口调用lock方法,就是从这里开始的
     * 底层,是调用了Sync类内部的lock方法
     * lock方法调用步骤:reentrantlock对象调用lock方法 -> 到这里调用Sync的lock方法 ->
     * Sync的lock方法是抽象方法,所以要调用子类(公平锁或非公平锁)重写的lock方法
     * 如果是非公平锁,为了追求效率,会先进行一次cas操作,失败了才会尝试获取锁
     * 通过至少调用一次tryAcquire方法并返回成功来实现。
     * 否则,线程将排队,并可能反复阻塞和解除阻塞,并一直调用tryAcquire方法直到成功
     *
     * 公平锁的话,则是直接尝试获取锁,即直接调用acquire方法
     */
    public void lock() {
        sync.lock();
    }

    /**
     * 调用父类Sync的lockInterruptibly方法
     * Sync的lockInterruptibly方法是直接继承的AQS的方法
     * @throws InterruptedException
     */
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }

    /**
     * 调用sync对象中的nonfairTryAcquire方法
     * @return
     */
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }

    /**
     * 调用sync对象中重载的tryLock方法
     * tryAcquireNanos方法是直接继承自AQS的
     * 多了一个超时放弃功能
     * @param timeout
     * @param unit
     * @return
     * @throws InterruptedException
     */
    public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

    /**
     * 尝试释放锁
     */
    public void unlock() {
        sync.release(1);
    }

    /**
     * 获取Condition对象,调用了父类Sync的方法
     * 底层是调用了AQS中的静态内部类ConditionObject的无参构造器
     * ConditionObject继承了Condition类
     * @return
     */
    public Condition newCondition() {
        return sync.newCondition();
    }

    /**
     * 获取当前state值,也即上锁次数
     * @return
     */
    public int getHoldCount() {
        return sync.getHoldCount();
    }

    /**
     * 判断是否被当前线程上锁
     * @return
     */
    public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }

    /**
     * 判断是否上锁,即判断state值是否为0
     * @return
     */
    public boolean isLocked() {
        return sync.isLocked();
    }

    /**
     * 判断是否是公平锁
     * @return
     */
    public final boolean isFair() {
        return sync instanceof FairSync;
    }

    /**
     * 获取当前持有锁的线程
     * @return
     */
    protected Thread getOwner() {
        return sync.getOwner();
    }

    /**
     * 判断当前线程队列是否有正在等待的线程
     * @return
     */
    public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }

    /**
     * 判断当前线程队列中,是否存在某线程
     * @param thread
     * @return
     */
    public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }

    /**
     * 获取当前线程队列的长度
     * @return
     */
    public final int getQueueLength() {
        return sync.getQueueLength();
    }

    /**
     * 返回当前线程队列的集合,ArrayList
     * @return
     */
    protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }

    /**
     * 如果传入的condition对象为null,则抛出NullPointerException异常
     * 如果传入的对象不是AQS类下的内部类ConditionObject的实例对象或子类对象则抛出IllegalArgumentException异常
     * <p>
     * 否则调用AQS类下的hasWaiters方法,判断是否有正在等待的线程
     * 但是由于超时和中断可能随时发生,因此并不能保证等待队列中的线程会被唤醒
     * 此方法主要被设计用于监视系统状态
     *
     * @param condition
     * @return
     */
    public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    /**
     * 获取等待队列的长度,即等待队列中等待线程的数量
     * @param condition
     * @return
     */
    public int getWaitQueueLength(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    /**
     * 获取等待队列中的正在等待的线程的ArrayList集合
     * @param condition
     * @return
     */
    protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }

    public String toString() {
        Thread o = sync.getOwner();
        return super.toString() + ((o == null) ?
                                   "[Unlocked]" :
                                   "[Locked by thread " + o.getName() + "]");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值