显式锁和AQS

ReentrantLock和Synchronized的异同点:

显式锁和AQS_第1张图片

总结

实现锁的关键在于:

  1. 通过CAS操作与volatile变量互相配合,线程安全的修改锁标志位
  2. 基于CLH队列,实现锁的排队策略,对于公平锁,当前线程只需要监控他的前驱节点的锁情况,当前锁持有这肯定是头节点

个人理解记录

ReentrantLock基于aqs实现,他的基本原理是aqs的status为0时表示锁被占用,为1时表示锁被释放。ReentrantLock在使用时需要显式的获取和释放锁,一般用try finally来实现,相对于synchronized,reentrantlock提供了功能更强大的api,例如超时锁、可中断锁、公平锁、非公平锁、非阻塞锁获取等等,ReentrantLock是独占锁,它分为公平锁和非公平锁两种模式,公平锁保证按照获取锁的顺序来得到锁,非公平锁则则可以进行抢占,而像countdownlatch、semaphore等组件是基于共享锁实现的,也就是同一时刻可以有多个线程获取锁,锁的数量由用户指定

独占公平锁原理: 
调用aqs的lock方法尝试获取锁 
调用上层组件reentrantlock的trylock方法尝试获取同步状态 
如果获取成功,则成功获取锁,如果获取失败,则被构造成node节点后,利用cas线程安全的加到同步对列的末尾 
然后该线程进入自旋状态 
自旋时首先判断前驱节点是否为头节点并且能否成功获取到同步状态,如果都成立,则成功获取锁,如果不成立,则先讲将其前驱节点等待状态设置为signal,然后利用Locksupport挂起,等待前驱线程唤醒当被前驱节点唤醒,且成功回去同步状态后,才成功获取到了锁。

对于释放锁,就是通过aqs设置同步状态为1的过程,同时唤醒后继节点

独占非公平锁: 
独占非公平锁与公平锁的唯一区别是,在获取锁时,不管是否有线程在等待锁,直接通过aqs修改同步状态,进行锁抢占,如果抢占失败,那后面的流程就与公平锁一致了。

共享锁原理: 
共享锁的基本流程与独占锁相同,主要区别在于判断锁获取的条件上,由于是共享锁,也就允许多个线程同时获取,所以同步状态的数量同时的大于1的,如果同步状态为非0,则线程就可以获取锁,只有当同步状态为0时,才说明共享数量的锁已经被全部获取,其余线程只能等待。 
共享锁的释放过程正好与之相反,释放锁对应的AQS操作时增加同步状态的值。

AQS同步队列的数据结构:详情请参考:https://www.jianshu.com/p/cc308d82cc71

  1. 同步队列是一个双向队列,AQS通过持有头尾指针管理同步队列
  2. 节点的数据结构,即AQS的静态内部类Node,节点的等待状态等信息

显式锁和AQS_第2张图片

1、显式锁和AQS  

显式锁

Lock接口和核心方法

Lock接口和synchronized的比较

synchronized 代码简洁,Lock:获取锁可以被中断,超时获取锁,尝试获取锁,读多写少用读写锁

可重入锁ReentrantLock、所谓锁的公平和非公平

如果在时间上,先对锁进行获取的请求,一定先被满足,这个锁就是公平的,不满足,就是非公平的

非公平的效率一般来讲更高

ReadWriteLock接口和读写锁ReentrantReadWriteLock

ReentrantLock和Syn关键字,都是排他锁,

读写锁:同一时刻允许多个读线程同时访问,但是写线程访问的时候,所有的读和写都被阻塞,最适宜与读多写少的情况

Condition接口

用Lock和Condition实现等待通知

了解LockSupport工具

park开头的方法

unpark(Thread thread)方法

AbstractQueuedSynchronizer深入分析

什么是AQS?学习它的必要性

AQS使用方式和其中的设计模式

了解其中的方法

AQS中的数据结构-节点和同步队列

节点在同步队列中的增加和移出

独占式同步状态获取与释放

其他同步状态获取与释放

Condition分析

 

 

 

 

 

 

你可能感兴趣的:(线程学习总结)