AQS(面试)
Posted 钢铁-程序猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AQS(面试)相关的知识,希望对你有一定的参考价值。
文章目录
AQS(面试)
AQS的全称是AbstractQueuedSynchronizer
AQS内部维护一个状态state,通过原子更新(CAS)这个状态变量可实现加锁解锁操作。
如果要实现自己的锁,可以基于AQS,重写tryAcquire,tryRelease,lock(会调用tryAcquire),unlock(tryRelease)方法。
基于AQS的ReentrantLock
ReentrantLock中主要定义了三个内部类:Sync、NonfairSync、FairSync。
ReentrantLock实现了Lock接口,Lock接口里面定义了java中锁应该实现的几个方法:
// 获取锁
void lock();
// 获取锁(可中断)
void lockInterruptibly() throws InterruptedException;
// 尝试获取锁,如果没获取到锁,就返回false
boolean tryLock();
// 尝试获取锁,如果没获取到锁,就等待一段时间,这段时间内还没获取到锁就返回false
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 释放锁
void unlock();
// 条件锁
Condition newCondition();
公平锁获取锁的过程总结
获取锁的主要过程大致如下:
- 1、先判断有没有锁(state==0)。
- 2、如果没有锁且没有线程在排队,则尝试获取锁(CAS),如果获取到了就直接返回了;
- 3、尝试获取锁失败,会判断占有锁的线程是不是当前现场,如果是则state+1,获取锁成功
- 4、如果获取锁失败且占有锁的线程不是当前线程,则会新建一个节点,CAS插入尾部,入队。
- 5、如果入队没成功,调用enq方法,不断尝试入队。
- 6、循环执行,判断当前节点的前面一个节点是不是head,如果是则尝试获取锁,获取成功则返回。
- 7、如果前面一个节点不是head或者没获取到锁,在循环过程中可能会park/
非公平锁过程总结
- 1、非公平锁一上来就会尝试获取锁,不管队列中有没有其他线程。
- 2、如果没有获取到,则会继续tryAcquire方法继续尝试获取锁。
条件锁
条件锁,是指在获取锁之后发现当前业务场景自己无法处理,而需要等待某个条件的出现才可以继续处理时使用的一种锁。
await、signal
条件锁维护一个条件队列。
await大致流程
- 1、新建一个节点加入到条件队列中去;
- 2、完全释放当前线程占有的锁;
- 3、阻塞当前线程,并等待条件的出现;
- 4、条件已出现(此时节点已经移到AQS的队列中),尝试获取锁;
以上是关于AQS(面试)的主要内容,如果未能解决你的问题,请参考以下文章