五.多线程进阶之各种锁
并发复习笔记之第五章(多线程进阶之锁)
想看后续请持续关注
以下来源有书籍 深入理解 JVM 虚拟机,java 并发编程的艺术,深入浅出多线程,阿里巴巴技术手册以及一些公众号 CS-Notes,JavaGuide,以及一些大厂高频面试题吐血总结,以及狂神说视频笔记,目的在于通过问题来复习整个多线程,已下是全部章节,觉得不错点个赞评论收藏三连一下,您的鼓励就是我继续创作的最大动力!!!!
5.1 Lock接口
5.1.1 lock 与 synchronize 区别
lock : 了锁获取与释放的可操作性、可中断的获取锁以 及超时获取锁,可以设置为公平锁
synchroized : 隐式的释放锁,不可以中断获取和超时获取,不可以设置为公平锁
5.2 AQS 同步队列
5.2.1 AQS 是什么
AQS是 AbstractQueuedSynchronizer的简称,即 抽象队列同步器 ,从字⾯意思上理解:
5.2.2 AQS 是用来干什么的?
那AQS 有什么⽤呢?AQS 是⼀个⽤来构建锁和同步器的框架,使⽤AQS 能简单且 ⾼效地构造出应⽤⼴泛的同步器,⽐如我们提到的ReentrantLock,Semaphore,ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的。
5.2.3 AQS如何使用?
同步器的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状 态
同步器的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的 方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模板方法,而这些 模板方法将会调用使用者重写的方法。
5.2.4 AQS 实现分析
5.2.4.1 Node节点的属性类型与名称以及描述
当前线程获取 同步状态失败时,同步器会将当前线程以及等待状态等信息构造成为一个节点(Node)并将其 加入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再 次尝试获取同步状态。
5.2.4.2 同步队列基本结构
同步器拥有首节点(head) 和尾节点(tail),没有成功获取同步状态的线程将会成为节点加入该队列的尾部
同步器将节点加入到同步队列的过程
首节点的设置:首节点是获取同步状态成功的节点,首节点的线程在释放同步状态 时,将会唤醒后继节点,而后继节点将会在获取同步状态成功时将自己设置为首节点
5.2.4.3 独占式同步状态获取与释放
此处推荐阅读源码,搞清楚 reentantlock 的实现机制,也是面试中的一个亮点
下面是整个流程图
5.3 重入锁
5.3.1 什么是重入锁?
重入锁保证了一个线程可以对一个资源重复加锁
5.3.2 重入锁的实现原理-源码
- 线程获取锁-锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再 次成功获取。
- 线程释放锁 - 锁的最终释放要求锁对于获取进行计数自增,计数表示当前锁被重复获取的次数,而锁 被释放时,计数自减,当计数等于0
时表示锁已经成功释放。
5.4 公平锁和非公平锁
5.4.1公平锁和非公平锁是什么?
公平性与否是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求的绝对时间顺序,也就是FIFO。
5.4.2 公平锁和非公平锁的对比
- 公平性锁保证了锁的获取按照FIFO原则,而代价是进行大量的线程切换,线程饥饿
- 非公平锁没有保证 FIFO 顺序,少量切换,避免了线程饥饿
5.4.3 公平锁和非公平锁获取锁的区别
唯一不同的位置为判断条件多了 hasQueuedPredecessors()方法,即加入了同步队列中当前节点是否有前驱节点的判断,如果该 方法返回true
5.5 锁的通信
5.5.1 condition 是什么 ?
Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式
5.5.2 condition 和 synchronize在通信中的区别?
下面画红线的地方是重点