并发编程之AQS和锁

一、AQS

1、AQS(AbstractQueuedSynchronizer抽象类):是一个用于构建锁和同步容器的框架(通过继承AQS并实现它的抽象方法),它不是通过synchronized给对象加锁实现的,而仅仅只是一个工具类。
JUC包内许多类都是基于AQS构建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,FutureTask等。

2、实现

AQS内部实现主要是状态变量state(volatile类型)和一个FIFO队列来完成,同步队列的头结点是当前获取到同步状态的结点,获取同步状态state失败的线程,会被构造成一个结点(或共享式或独占式)加入到同步队列尾部(采用自旋CAS来保证此操作的线程安全),随后线程会阻塞;释放时唤醒头结点的后继结点,使其加入对同步状态的争夺中。

state:ReentrantLocky用它表示线程重入锁的次数,Semaphore用它表示剩余的许可数量,FutureTask用它表示任务的状态。 对state变量值的更新都采用CAS操作保证更新操作的原子性。 

3、AQS功能

1、独占锁:ReentrantLock

2、共享锁:CountDownLatch等

4、如何自己实现

1、继承AbstractQueuedSynchronizer这个类;
2、然后根据需求去重写相应的方法,要实现一个独占锁,那就去重写tryAcquire,tryRelease,要实现共享锁,就去重写tryAcquireShared,tryReleaseShared;
3、在我们的组件中调用AQS中的模板方法就可以了,而这些模板方法是会调用到我们之前重写的那些方法的;

5、设计思想

AQS实现是经典的模板方法模式:只需要很小的工作量(重写方法)就可以实现自己的同步组件,AQS为我们定义好顶级逻辑的骨架,并提取出公用的线程入队列/出队列,阻塞/唤醒等一系列复杂逻辑的实现,将部分简单的可由使用者决定的操作逻辑延迟到子类中去实现即可。

二、锁

synchronized:可以保证原子性、可见性和有序性;
CAS(Compare And Swap):原子操作,可以保证原子性
volatile:可以保证可见性、有序性

阻塞队列BlockingQueue和并发容器ConcurrentMap中的很多同步都是通过ReentrantLock实现的。但ConcurrentHashMap在jdk1.8中换成了CAS+synchronized。AQS是API级别的后续优化空间很小,Synchronized是JVM直接支持的,有锁粗化、锁消除、锁自旋特性,可以直接随JDK版本升级而提升。

Ref:

https://www.cnblogs.com/chengxiao/archive/2017/07/24/7141160.html

https://blog.csdn.net/luofenghan/article/details/75065001

猜你喜欢

转载自my.oschina.net/u/3787772/blog/2088097