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();
}
}
加架构群:948368769领取架构资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!