Java的reentrant lock源码阅读

这里是我自己阅读源码时留下的注释,和代码。
上面都写了我的理解和对官方英文的翻译,截取了我认为比较常见的和重要的部分贴了上来
看之前可以看看AbstractQueuedSynchronizer这个抽象类的源码。能更好的理解Java中的各种lock类

这部分源码看下来
发现这个lock就是对AbstractQueuedSynchronizer这个类中的state进行修改来实现 锁的逻辑的
这个是重入锁那么一个线程第一次获取会把state从0变成1,后面如果他再次获取就会累计加1
释放时也是一次减去1
这就是重入的逻辑

public class ReentrantLock implements Lock, java.io.Serializable {
    private static final long serialVersionUID = 7373984872572414699L;
    /** Synchronizer providing all implementation mechanics */
    private final Sync sync;

    
    
    //继承自之前看的AbstractQueuedSynchronizer抽象类的CLH队列
    //这里依旧是一个抽象类
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        
        abstract void lock();

        /**
         * 
         * 执行不公平的tryLock。 tryAcquire是在子类中实现的,
         * 但是都需要对trylock方法进行不公平的尝试。
         * 
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();//取得当前线程
            int c = getState();//取得aqs内维护的整形state
            if (c == 0) {//如果==0那么就是第一次进入
                if (compareAndSetState(0, acquires)) {//直接修改cas的方式state
                    setExclusiveOwnerThread(current);//设置这个lock的所有者线程为当前线程
                    //这个所有者线程就是代表了刚刚已经进入过的线程,下一次要是还进入这个线程就算她重入
                    //不需要从0开始设置state
                    return true;
                }
            }
            //这就是刚刚说的第二种情况,这个线程为所有者线程的情况
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;//对state进行累加,而不是从0开始
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

        //尝试释放锁的方法
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;//首先获取state-releases
            //这么做是因为这是个可重入的锁,可能state已经累加了多次了
            //这只是释放第一层锁
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {//这里释放了一次就==0了说明锁全部释放了
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);//更新state
            return free;
        }

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

        final ConditionObject newCondition() {
            return new ConditionObject();
        }

        // Methods relayed from outer class

        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
        }
    }
    //-------------从这里开始抽象队列同步器的代码结束

    //--------------下面是非公平的抽象队列同步器代码
    /**
     * Sync object for non-fair locks
     * 这里继承了上面那个sync
     * sync实现了释放和获取锁的逻辑
     */
    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() {
            if (compareAndSetState(0, 1))//修改state成功从0变为1
                //设置所有者线程
                setExclusiveOwnerThread(Thread.currentThread());
            else//修改失败
                acquire(1);//调用acquire方法修改为1
        }

        //非公平的acquire
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }
    
    //-----------下面是公平的抽象队列同步器实现逻辑

    /**
     * Sync object for fair locks
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            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;
        }
    }
    //-------------内部的抽象队列同步器代码结束
    
    //-----------构造方法的区域-----------
    /**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    //根据这个代码看默认是非公平的锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    //这里是设置公平锁和非公平锁的构造器
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

    //----------到这里构造器也全部结束了,下面的方法都是对上面方法和condition方法的封装

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值