源码解读 可重入锁ReentrantLock 的内部类 公平锁FairSync 和 非公平锁NonfairSync 实现原理

变量解释:

public abstract class AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
    /** * The current owner of exclusive mode synchronization. * 持有该锁的当前线程 */
    private transient Thread exclusiveOwnerThread;
    ...
}
public abstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable {
    ...
    /**
     * The synchronization state.
     * 0: 初始状态-无任何线程得到了锁
     * > 0: 被线程持有, 具体值表示被当前线程持有的执行次数
     * 
     * 这个字段在解锁的时候也需要用到。
     * 注意这个字段的修饰词: volatile
     */
    private volatile int state;
    ...
}

 

公平锁FairSync:

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

        final void lock() {
            // AQS的acquire方法。独占方式。尝试获取资源,成功则返回true,失败则返回false。
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         * (翻译:tryAcquiere的公平锁实现版本,除非有递归、没有等待者、或者有优先,否则不要授予锁权限)
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            // AQS使用一个int类型的成员变量state来表示同步状态,当state = 1时表示已经获取了锁,当state = 0时表示释放了锁。
            // getState():返回同步状态的当前值;
            int c = getState();
            if (c == 0) { // 如果当前线程没有获取过锁,则尝试加锁
                //与非公平锁不同的是,此处多了hasQueuedPredecessors()判断,该方法是实现公平锁的关键。
                //如果hasQueuedPredecessors返回true,表示有其他线程先于当前线程等待获取锁,此时为了实现公平,保证等待时间最长的线程先获取到锁,不能执行CAS。

                //protected final boolean compareandsetstate(int expect, int update) 
                //如果当前状态值等于预期值,则以原子方式将同步状态设置为给定的更新值。此操作具有 volatile 读和写的内存语义。
                //参数:expect - 预期值 update - 新值
                //返回:如果成功,则返回 true。返回 false 指示实际值与预期值不相等。
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {

                    // 设置占用排它锁的线程是当前线程
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // getExclusiveOwnerThread(): 返回由 setexclusiveownerthread 最后设置的线程;如果从未设置,则返回 null。此方法不另外施加任何同步或 volatile 字段访问。
            else if (current == getExclusiveOwnerThread()) { //当前线程已经获取到锁,重入
                int nextc = c + acquires; // 锁状态计数器累加
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

 

非公平锁NonfairSync:

    /**
     * Sync object for non-fair locks
     */
    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))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

FairSync:

NonfairSync:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenLeungX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值