AQS原理之ReentrantLock

AQS原理之ReentrantLock
aqsreentrantlock
AQS即是AbstractQueuedSynchronizer,一个用来构建锁和同步工具的框架,包括常用的ReentrantLock、CountDownLatch、Semaphore等。
AQS没有锁之类的概念,它有个state变量,是个int类型,在不同场合有着不同含义。本文研究的是锁,为了好理解,姑且先把state当成锁。
AQS围绕state提供两种基本操作“获取”和“释放”,有条双向队列存放阻塞的等待线程,并提供一系列判断和处理方法,简单说几点:
- state是独占的,还是共享的;
- state被获取后,其他线程需要等待;
- state被释放后,唤醒等待线程;
- 线程等不及时,如何退出等待。
一边debug, 一边画图...基本获取锁的机制,和AQS的队列画出来了, 搞了两小时,贼TM累。。。非公平的就不画了
/**
* 最开始 tail = null, head =null, state = 0
* 1.线程0获取锁,state = 1, exclusiveOwnerThread = 线程0,
* 2.线程1进入,因为state = 1, 所以tryAcquire 失败,执行 addWaiter(Node.EXCLUSIVE), 构造一个新Node(728),
* 因为tail = null,所以执行 enq(node), 因为tail = null, 创建一个新Node赋值给head,
* 此时head = Node(748,这里的748是为了标志对象,实际值不确定),并tail = head;
* 此时 tail = head = Node(748)
* 然后第二次循环, t = tail; Node(728).prev = tail; compareAndSetTail(t, node);成功则tail = Node(728);
* 此时 head = Node(748), tail = Node(728), tail.prev = head = Node(748);然后 t.next = node; 即 head.next = tail;
*
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(() -> {
lock.lock();
System.out.println("ThreadName=" + Thread.currentThread().getName());
}).start();
}
}