AQS提供了两种锁的机制,一种是排他锁,一种是共享锁,所谓排他锁就是存在多个线程去竞争统一共享资源时,同一时刻只允许一个线程去访问这样一个共享资源,比如lock中的ReentrantLock。共享锁也叫读锁,同一时刻允许多个线程获得这样一个锁的资源,比如Semaphore和CountDownLatch。AQS设计中需要解决三个核心问题
互斥变量的设计以及如何保证多线程同时更新互斥变量的时候线程的安全性;未竞争到资源的锁的等待和竞争到锁的资源释放锁之后的唤醒;锁竞争的公平性和非公平性
AQS采用了int类型的互斥变量state来记录锁的竞争状态,0表示没有线程获得资源,大于等于1说明有线程正在持有锁资源。线程来获得锁资源时会判断state是否为0,如果不是就更新为1,表示占用锁。在这个过程中多个线程同时做这样的操作,就会导致线程的安全性问题,AQS采用CAS来保证state互斥变量更新的原子性。未获得到锁的线程通过unsafe类中的park方法去进行阻塞,把阻塞的线程按照先进先出的原则去加入到一个双向链表的一个结构中,当获得锁资源的线程释放锁之后,会从这样一个双向链表的头部去唤醒下一个等待的线程再去竞争锁。最后关于锁竞争的公平性和非公平性的问题,AQS的处理方法是在竞争锁资源的时候公平锁需要去判断双向链表中是否有阻塞的线程,如果有就需要排队等待,而非公平锁的处理方式是不管双向链表中是否存在等待竞争锁的线程,那么他都会直接去尝试更改互斥变量state去竞争锁。假设在一个临界点,获得锁的线程释放锁,此时state等于0,而当前的这个线程去抢占锁的时候正好可以把state修改成1,那么这个时候就可以表示他可以拿到锁,而这个过程是非公平的