网站首页 > 博客文章 正文
下面我们从一些源码的角度来看看JUC包中lock锁的经典实现ReentrantLock,并且看看AbstractQueuedSynchronizer(AQS,下面就以该简称叙述了)同步器的底层实现。
本篇内容较多,希望大家耐心看完,比较难,不是很好理解,如有错误的地方,望大家海涵。标题只是为了吸引眼球,但两者确实有着千丝万缕的关系。因为想要搞明白Java的重入锁ReentrantLock,你必须要明白AQS;要想搞明白AQS,ReentrantLock锁的辅助分析又必不可少,所以我就两个一起看了。
Lock和synchronized的区别
在我们之前学习synchronized时,我们也说到,在JDK1.6之前效率是很低的,但是和LOCK相比较,还是有着很大的差距;在1.6之后做了很大的优化和提升(锁优化升级),相比较而言,性能上和LOCK相差无几;
虽然synchronized隐式地帮助我们实现了我们想要的锁的功能(不用我们自己操心如何上锁、解锁),但是缺少了上锁和解锁的可操作性,导致一些问题的不可控,且它为独占式的锁,在真正的高并发场景是满足不了我们的需求的;而Lock支持中断和超时、还支持尝试机制获取锁,提高了可控性和可操作性; 且在JUC包下的有着很多锁的实现,可以在不同的需求场景应用合适的锁。
下面就跟着笔者,打开工具idea/eclipse来进入源码世界吧,具体源码位置如下图:
从类关系UML图大概了解AQS和Lock的关系
从上图中我们可以看到,这里有两个顶级接口,Lock和Condition,上源码
Lock就是锁的顶级父类,定义了几个加锁和释放锁的方法,还有一个就是可以新建条件等待队列的方法newCondition();
Condition按照我的理解它代表某个条件,意思就是如果某个条件还没达成,就会建立一个等待条件达成的等待队列,这个等待队列里放的都是些等待这个条件可行的线程。观其定义的一些方法,就跟我们之前篇幅里讲wait/notify范式类似,其实他们的原理都是相通的。其中的await就相当于wait(),signal()/signalAll()相当于notify()/notifuAll()。我们后面都会去分析的。
再回到上面的UML图,刚刚我们只是简单介绍了下两个顶级父接口,这里我们还有一个抽象类AbstractOwnableSynchronizer,他是我们主角AQS的父类。如下
这个类中只定义了一个属性exclusiveOwnerThread(当前独占模式所有者,本质是一个线程,独占模式什么意思后续会说),其他什么也没有,为什么就这么一个属性要单独搞个父类呢,我们观其父类的子类其实是有两个,还有一个AbstractQueuedLongSynchronizer,其实这个类就是AbstractQueuedSynchronizer的一个补充实现,就是里面的资源state变量,一个是int型,还有一个是long型而已。。。一般情况下,用不到哈~
再继续,我们看我们的主角AbstractQueuedSynchronizer类,观其类名就应该知道,这个类大概就是抽象的同步队列,既然是队列,那意思就是说,我们这个类里面维护了一个队列,学过数据结构的我们都知道,队列的建立一般都需要节点Node,这时我们再看UML图,在我们AQS的内部确实实现了一个Node的类。
这个节点类呢其实就是用来包装线程的,他给出了进入队列线程的一些额外属性,比如当前的状态,它前面的线程节点,后面的线程节点等等。由此我们看出,AQS它就是一个用来管理同步线程队列的一个类。
再继续,我们看到了Lock的一个实现类(另一个主角),重入锁ReentrantLock,观其内部,一共继承AQS实现了三个类,一个Sync,还有两个继承了Sync,分别是NonfairSync(非公平)和FairSync(公平),其实这两个类就是我们之前讲过的公平和非公平锁的体现了。
由于内容和篇幅较长,我们明天会继续讲解这个内容哦!
猜你喜欢
- 2024-10-16 “全栈2019”Java多线程第三十一章:如何中断锁上正在等待的线程
- 2024-10-16 阿里巴巴Java性能调优实战:深入了解Lock同步锁的优化方法
- 2024-10-16 线程池:治理线程的法宝(线程池的实现原理和实现方法)
- 2024-10-16 程序员必须要知道的ReentrantLock 及 AQS 实现原理
- 2024-10-16 synchronized 和 ReentrantLock 的实现原理是什么?它们有什么区别
- 2024-10-16 Java线程池核心(十五):工作线程Worker
- 2024-10-16 一文搞懂分布式可重入锁(分布式锁的实现方式及优缺点)
- 2024-10-16 从Java线程池的常用4种写法深入分析线程池的实现原理
- 2024-10-16 Java基础——Java多线程(Lock接口详解)
- 2024-10-16 ReentrantLock原理及详细的使用方法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)