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();
    }
}

AQS原理之ReentrantLock_唤醒等待

AQS原理之ReentrantLock_双向队列_02

AQS原理之ReentrantLock_处理方法_03

AQS原理之ReentrantLock_处理方法_04