多线程-ReentrantLock

ReentrantLock 支持公平锁和非公平锁(通过构造函数设置),默认情况下为非公平锁
image

ReentrantLock 内部维护了两个同步器类 NonfairSync(非公平锁) 和 FairSync(公平锁)
image

Sync 继承子AQS(AbstractQueuedSynchronizer)

非公平锁加锁流程(NonfairSync.lock 方法)

image
加锁成功流程:通过CAS操作将AQS的状态设置为1,然后将owner设置为当前线程
加锁失败进入acquire:
image
首先还是会进行加锁操作,失败会先创建一个和线程相关的Node,加入到node队列里,如果node队列为空就进行构造一个node队列,队列的头结点不和任何线程相关 。
image

进行阻塞前还是会判断是否是第一个和线程相关的结点,如果是则再次尝试进行加锁,失败后会进行判断是否阻塞
image

image

shouldParkAfterFailedAcquire 方法主要是讲当前结点的前驱结点的状态设置为-1(目的前驱结点有责任将后继结点唤醒进行抢锁操作),parkAndCheckInterrupt 方法主要是让线程休眠,等待唤醒。

image

非公平锁解锁流程

image

根据头结点来找到第一个休眠的线程进行唤醒,并将原先的头结点删除,讲当前结点置为头结点,唤醒的线程执行上面for循环的代码进行加锁操作

image

可重入原理

会判断owner的线程是否为当前线程,如果是对状态进行累加操作(装态为0无锁 无锁则进行加锁操作,1有锁进行累加),解锁则进行减1操作并判断状态是否为0
image

posted @ 2022-03-21 16:06  原来是晴天啊  阅读(72)  评论(0编辑  收藏  举报