AQS原理
1、AbstractQueuedSynchronizer是阻塞式和相关的框架
特点:
用state属性来表示资源的状态(分独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁。
getState - 获取state状态
setState - 设置state状态
compareAndSetState-乐观锁机制设置state状态
独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源。
提供了基于FIFO的等待机制,类似于Monitor的EntryList
条件变量来实现等待,唤醒机制,支持多个条件变量,类似于Monitor的waitSet
2、子类主要实现的方法(默认会抛出异常UnsupportedOperationException)
2.1tryAcquire
2.2tryRelease
2.3tryAcquireShared
2.4isHeldExclusively
获取锁
阻塞用的park unpark
释放锁
ReentrantLock原理
非公平锁:
lock(){
//未出现竞争
compareAndSetState(0,1)
setExclusiveOwnerThread(Thread.currentThread);
//竞争
acquire(1)
}
acquireQueued(addWaiter(Node.Exclusive))//创建一个节点对象,加入到队列中。
首次加入addwait会创建两个节点(Dummy,哨兵)
dummy占位
进入shouldParkAfterFailedAcquire逻辑,将前驱node,即head的waitStatus改为-1,这次返回false
release()函数中
unparkSuccessor(h);//唤醒后继节点
可重入原理
对state进行累加或者减
如果state减为0了,锁就释放成功。
条件变量实现原理
await
ReentrantLock
实现了Lock接口,静态内部类sync继承了AQS,重写了AQS的一些方法。
1、可中断
2、可以设置超时时间
3、设置为公平锁 ,默认非公平
4、支持多个条件变量。
//打断机制
lock.lockInterruptibly();
如果没有竞争那么次方法就会获取lock对象锁
如果有竞争就会进入阻塞队列,可以被其他线程用interrupt方法打断;
lock.interrupt();
//设置超时时间
立刻主动失败
lock.tryLock(1000)
//设置公平锁、非公平锁
静态内部类 AQS