AQS
在java中有两种锁机制,一种是Synchronized关键字,这个java自带的内置锁,其中的加锁和解锁的逻辑不用我们去实现。还有一种是JUC包下面的Lock,这是一种显示锁,需要我们手动完成加锁和解锁(其中解锁的逻辑一定要在try/catch中的finally中编写,不然可能会出现死锁问题),这种显示锁就需要用到AQS。
AQS提供了一些模板方法,具体的细节实现交给其他锁。比如ReentrantLock,CountDownLaunch等
全称AbstractQueuedSynchronizer(抽象队列同步器),对比Synchronized,要实现线程同步,有三点必须要满足:
1.线程获取锁的过程。AQS中大量使用的CAS来保证同一时刻只能有一个线程获取到锁。
2.线程的阻塞与唤醒。使用内部的条件队列Condition,借助了Locksupport中的park/unpark,底层实现是操作系统的mutex互斥量。
3.线程阻塞的等待队列。在AQS中定义一个Node内部类,维护了一个双向链表,用来维护线程的状态。在AQS中还提供了一些方法,例如入队,出队等,也是使用CAS实现。
AQS具备特性:
- 阻塞等待队列
- 共享/独占
- 公平/非公平
- 可重入
- 允许中断