首页 > 技术文章 > 可重入的独占锁ReentrantLock概述-公平与非公平锁的实现

bllbl 2021-10-23 18:05 原文

类图概述

ReentrantLock是可重入的独占锁,R最终还是AQS来实现的,根据参数决定内部是否为公平锁。

其中Sync类继承AQS,重写了AQS提供的钩子方法,比如tryAcquire方法。AQS的state状态值标识线程获取该锁的次数。

image

非公平的实现

非公平是说先尝试获取锁的线程不一定比后尝试获取锁的线程优先获取锁。(人话:后尝试的线程也可能拿到锁)

实现过程:首先查看state是否为0,为0代表空闲,尝试CAS获取该锁,将state从0改为1,设置当前锁的持有者为自己然后返回。

例子:线程A调用lock方法,执行到nonfairTryAcquire的代码,发现state不为0,发现当前线程不是线程持有者,则返回false,然后当前线程被放入AQS阻塞队列。

这时线程B也调用了lock方法执行到nonfairTryAcquire,发现state为0了,B通过CAS获取了锁,这就是抢夺策略。

公平的实现

hasQueuedPredecessors方法是实现公平性的核心方法。

一句话概括:查询是否有线程等待获取的时间长于当前线程。

实现过程:如果当前线程节点有前驱结点则返回true,否则如果当前AQS队列为空或者当前节点是AQS的第一个节点则返回false。(为什么新来的线程还没入队就有前驱结点?这里应该是在讨论该节点已经入队的情况,该线程入队之后,通过查询线程前面还有没有前驱结点,来判断他是否能公平的获取锁)。

推荐阅读