获取锁的方式:
- lock():获取不到就休眠,且不响应中断;
- tryLock():获取不到就返回false;
- tryLock(timeOut):timeOut时间内获取不到就返回false;
- lockInterruptibly():功能和lock一样,但是可以相应中断,抛出异常;
公平锁:
公平锁的实现比非公平锁多调用了hasQueuedPredecessors方法,判断如果同步器队列中有线程等待,则直接接入队尾;
AQS
- 资源:state,全局共享,被设置为volatile,通过CAS来操作修改,获取锁就把state加一,为0代表没有线程持有0;
- 队列:AQS阻塞队列,所有等待锁的线程的集合,是一个CLH队列,头结点head不指向任何线程,是一个哑节点;
- exclusiveOwnerThread:记录了当前持有锁的线程;
两个队列
- AQS阻塞队列:线程竞争锁失败就会加入阻塞队列;
- Condition条件队列:线程调用await方法就会释放锁,加入条件变量对应的条件队列,如果其他线程调用signal或signalAll,就会有一个或全部节点从条件队列中移出,加入阻塞队列;
一个锁只有一个阻塞队列,
一个锁有多个条件变量,
一个条件变量有一个条件队列;
AQS获取锁
- 去尝试获取锁;
- 获取失败,则生成节点,加入队列尾部;
- 通过CAS设置,在并发的情况下,去循环处理尾分叉;
- 判断前置是否为head节点,是的话就再去获取一次锁;
- 获取成功就将state加一,并将exclusiveOwnerThread置为当前线程;