1、简介
AQS: abstractQueuedSynchronizer的简写
- 使用Node实现FIFO队列,可以用于构建锁或者其他同步装置的基础框架
- 利用了一个int类型表示状态
- 使用方法是继承
- 子类通过继承并通过实现它的方法管理器状态(acquire和release)的方法操作状态
- 可以同时实现排它锁和共享锁模式(独占、共享)
2、AQS同步组件
- CountDownLatch
- Semaphore
- CyclicBarrier
- ReentrantLock
- Condition
- FutureTask
- …
3、AQS的原理
AQS的核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态;如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。
CLH:是一个虚拟的双向队列,虚拟的双向队列即不存在队列实例,仅存在结点之间的关联关系,AQS是将每条请求共享资源的线程封装成一个CLH锁队列的一个结点来实现锁的分配。
4、AQS之CountDownLatch
- CountDownLatch是一个同步辅助类,可以用它完成类似线程阻塞的功能
- CountDownLatch使用一个给定的计数器进行计数,该计数器是一个原子性操作,调用该类的await()方法的线程会一直处于阻塞状态,直到其他线程调用countDown()方法将该计数器变为0(每次调用countDown的时候,该计数器的值会减1)
- 使用场景:程序执行需要等待某个条件后才能继续执行之后的操作。如:并行计算
5、AQS之semaphore(信号量)
- 可以用来控制并发访问的次数(简单来说就是并发数)
- 可用的方法为acquire和release,分别是获取一个许可和释放一个许可
- 使用场景:如数据库连接数,最大值可能只设置为200
6、AQS之CyclicBarrier
- 也是一个同步辅助类,允许一组线程相互等待,只有当每个线程都准备就绪后,才能各自继续往下执行。
- 举例说明:如果一个寝室四个人约好了去球场打球,由于四个人准备工作不同,所以约好在楼下集合,并且四个人集合好之后一起出发去球场。
7、AQS之ReentrantLock与锁
- ReentrantLock与synchronized都是可重入锁
- synchronized的锁是jvm实现的,而ReentrantLock是通过jdk实现的
- synchronized的性能在优化前性能差,但是现在两者相差不多,建议使用synchronized