摘要:前言回顾前面多线程三分钟就可以入个门了源码剖析多线程基础必要知识点看了学习多线程事半功倍锁机制了解一下简简单单过一遍只有光头才能变强上一篇已经将锁的基础简单地过了一遍了,因此本篇主要是讲解锁主要的两个子类那么接下来我们就开始吧一锁首先我们来
前言
回顾前面:
多线程三分钟就可以入个门了!
Thread源码剖析
多线程基础必要知识点!看了学习多线程事半功倍
Java锁机制了解一下
AQS简简单单过一遍
只有光头才能变强!
上一篇已经将Lock锁的基础AQS简单地过了一遍了,因此本篇主要是讲解Lock锁主要的两个子类:
ReentrantLock
ReentrantReadWriteLock
那么接下来我们就开始吧~
一、ReentrantLock锁首先我们来看看ReentrantLock锁的顶部注释,来看看他的相关特性呗:
来总结一下要点吧:
比synchronized更有伸缩性(灵活)
支持公平锁(是相对公平的)
使用时最标准用法是在try之前调用lock方法,在finally代码块释放锁
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }1.1内部类
首先我们可以看到有三个内部类:
这些内部类都是AQS的子类,这就印证了我们之前所说的:AQS是ReentrantLock的基础,AQS是构建锁、同步器的框架
可以很清晰的看到,我们的ReentrantLock锁是支持公平锁和非公平锁的~
1.2构造方法 1.3非公平lock方法尝试获取锁,获取失败的话就调用AQS的acquire(1)方法
acquire(1)方法我们在AQS时简单看过,其中tryAcquire()是子类来实现的
我们去看看tryAcquire():
1.4公平lock方法公平的lock方法其实就多了一个状态条件:
这个方法主要是判断当前线程是否位于CLH同步队列中的第一个。如果是则返回flase,否则返回true。
1.5unlock方法unlock方法也是在AQS中定义的:
去看看tryRelease(arg)是怎么实现的:
二、ReentrantReadWriteLock我们知道synchronized内置锁和ReentrantLock都是互斥锁(一次只能有一个线程进入到临界区(被锁定的区域))
而ReentrantReadWriteLock是一个读写锁:
在读取数据的时候,可以多个线程同时进入到到临界区(被锁定的区域)
在写数据的时候,无论是读线程还是写线程都是互斥的
一般来说:我们大多数都是读取数据得多,修改数据得少。所以这个读写锁在这种场景下就很有用了!
读写锁有一个接口ReadWriteLock,定义的方法就两个:
我们还是来看看顶部注释说得啥吧:
其实大概也是说明了:在读的时候可以共享,在写的时候是互斥的
接下来我们还是来看看对应的实现类吧:
按照惯例也简单看看它的顶部注释:
于是我们可以总结出读写锁的一些要点了:
读锁不支持条件对象,写锁支持条件对象
读锁不能升级为写锁,写锁可以降级为读锁
读写锁也有公平和非公平模式
读锁支持多个读线程进入临界区,写锁是互斥的
2.1ReentrantReadWriteLock内部类ReentrantReadWriteLock比ReentrantLock锁多了两个内部类(都是Lock实现)来维护读锁和写锁,但是主体还是使用Syn:
WriteLock
ReadLock
2.2读锁和写锁的状态表示在ReentrantLock锁上使用的是state来表示同步状态(也可以表示重入的次数),而在ReentrantReadWriteLock是这样代表读写状态的:
2.3写锁的获取主要还是调用syn的acquire(1):
进去看看实现:
2.4读锁获取写锁的获取调用的是acquireShared(int arg)方法:
内部调用的是:doAcquireShared(arg);方法(实现也是在Syn的),我们来看看:
三、最后这里就简单总结一下本文的内容吧:
AQS是ReentrantReadWriteLock和ReentrantLock的基础,因为默认的实现都是在内部类Syn中,而Syn是继承AQS的~
ReentrantReadWriteLock和ReentrantLock都支持公平和非公平模式,公平模式下会去看FIFO队列线程是否是在队头,而非公平模式下是没有的
ReentrantReadWriteLock是一个读写锁,如果读的线程比写的线程要多很多的话,那可以考虑使用它。它使用state的变量高16位是读锁,低16位是写锁
写锁可以降级为读锁,读锁不能升级为写锁
写锁是互斥的,读锁是共享的。
总的来说看多线程源码难度系数还是好高啊,我目前的水平只能过一过了....
多线程后面还有挺多高深的知识点:Future、同步容器啊、阻塞队列、各种原子类啊等等等,这里我打算就先放一放了,目前的水平有限啊~
后面可能会有一篇线程池的博文,敬请期待咯~
有兴趣的同学可继续往下面的参考资料下学习~~~
参考资料:
http://cmsblogs.com/?page_id=111
如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y。为了大家方便,刚新建了一下qq群:742919422,大家也可以去交流交流。谢谢支持了!希望能多介绍给其他有需要的朋友
文章的目录导航:
https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69232.html
摘要:在多线程编程中我们会遇到很多需要使用线程同步机制去解决的并发问题,而这些同步机制就是多线程编程中影响正确性和运行效率的重中之重。这五个方法之所以能指定同步器的行为,则是因为中的其他方法就是通过对这五个方法的调用来实现的。 在多线程编程中我们会遇到很多需要使用线程同步机制去解决的并发问题,而这些同步机制就是多线程编程中影响正确性和运行效率的重中之重。这不禁让我感到好奇,这些同步机制是如何...
摘要:我在面试题中也见过他的身影,但一直不知道是什么东西。直到当前线程被或者获取到资源,结束。简简单单把过一遍明天就看显式锁实现咯参考资料如果文章有错的地方欢迎指正,大家互相交流。为了大家方便,刚新建了一下群,大家也可以去交流交流。 前言 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制了解一下 只有光头才能变强...
摘要:所谓的重入,就是当本线程想再次获得锁,不需要重新申请,它本身就已经锁了,即重入该锁。如果不为,则表示有线程已经占有了。总结回顾下要点是一个可重入的锁被当前占用的线程重入。 上一章《AQS源码阅读》讲了AQS框架,这次讲讲它的应用类(注意不是子类实现,待会细讲)。ReentrantLock,顾名思义重入锁,但什么是重入,这个锁到底是怎样的,我们来看看类的注解说明showImg(http:...
摘要:不同的是它还多了内部类和内部类,以及读写对应的成员变量和方法。另外是给和内部类使用的。内部类前面说到的操作是分配到里面执行的。他们都是接口的实现,所以其实最像应该是这个两个内部类。而且大体上也没什么差异,也是用的内部类。 之前讲了《AQS源码阅读》和《ReentrantLock源码阅读》,本次将延续阅读下ReentrantReadWriteLock,建议没看过之前两篇文章的,先大概了解...
摘要:之所以使用这种方式是因为在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。这样我们就可以把线程恢复运行的这段时间给利用起来了,结果就是线程更早的获取了锁,线程获取锁的时刻也没有推迟。 前言 系列文章目录 上一篇 我们学习了lock接口,本篇我们就以ReentrantLock为例,学习一下Lock锁的基本的实现。我们先来看看Lock接口中的方法与ReentrantLock对其实...
阅读 802·2021-09-22 15:18
阅读 1151·2021-09-09 09:33
阅读 2733·2019-08-30 10:56
阅读 1151·2019-08-29 16:30
阅读 1448·2019-08-29 13:02
阅读 1427·2019-08-26 13:55
阅读 1613·2019-08-26 13:41
阅读 1904·2019-08-26 11:56