ReentrantLock源码解析——一篇文章搞定ReentrantLock

一.概述

想要看懂ReentrantLock源码必须知道两个知识点

1.CAS,既比较并交换,是解决多线程并发情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作——内存位置(V),预期原值(A)和新值。进行操作时,如果内存位置的值和预期原值一样,则更新为新值,否则不做操作。

2.AbstractQueuedSynchronizer简称AQS:AQS是一个FIFO等待队列的阻塞锁和相关的同步器一个同步框架

首先看AQS源码中有几个属性:head,tail,state

head是首节点

tail是末节点

state记录加锁状态,0未加锁,大于0已加锁(重入次数)

内部类Node

prev,next,thread

看到这里,是不是很熟悉,AQS其实就是一个双向链表结构。

二.源码分析

ReentrantLock可以实现公平锁和非公平锁,默认是非共公平锁,构造方法参数boolean来初始化相应的锁

两个内部类:NonfairSync(非公平),FairSync(公平) 继承体系

源码开始第一步:NonfairSync加锁:

acquire里面主要有三个方法:

1.tryAcquire();尝试获取锁

2.addWaiteer()加入到队列

这个代码非常清晰,主要是构建双向链表,用compareAndSetTail保证串行化操作

注意一点:head和tail都是volatile修饰的,保证了可见性

private transient volatile Node head;

private transient volatile Node tail;

3.acquireQueued();自旋获取锁

这里是Node节点线程的自旋过程,主要检查节点是不是head节点的next节点,如果是则尝试获取锁,获得锁成功过,释放节点,返回结果。这样就是一个公平锁的流程

如果不是则一直自旋,主要是

shouldParkAfterFailedAcquire和parkAndCheckInterrupt 这两个方法

4.解锁过程 unlock();

主要是调用AQS同步器的release方法:

就是对state进行-1操作,当state=0是,清除当前线程,释放锁成功

最后:

看完这段源码对Lock有一定的认识了解,里面还有很多内容不是很清晰,需要去努力挖深学习。

如果文章有任何问题,请各位大神及时指出,通过学习进步

猜你喜欢

转载自blog.csdn.net/rongshisuo/article/details/88644596