并发编程灵魂拷问系列之对AQS理解吗


并发编程灵魂拷问系列之对AQS理解吗

AQS 即 AbstractQueuedSynchronizer,队列同步器。早期是因为JDK6以前的synchronized关键字使用的是重量级锁,性能不太好,所以作者编写了AQS。

在JUC中 CountDownLatch、ReentrantLock、ThreadPoolExecutor、ReentrantReadWriteLock 等底层用的都是AQS,AQS几乎占据了JUC并发包里的半壁江山,如果想要获取锁可以被中断、超时获取锁、尝试获取锁那就用AQS吧。

AQS内部维护了一个 先进先出队列state状态变量

  • 先进先出队列载体是 Node节点,节点里包含状态值,属于独占/共享模式,前驱/后继节点等信息
  • state由 volatile 修饰,标识当前锁的状态,1表示加锁成功 0未加锁

  1. 当线程1操作CAS加锁成功,AQS中的加锁线程变为线程1,state设置为1。
  2. 与此同时线程2加锁失败会进入FIFO先进先出等待队列,当线程1执行完成后,state设为0,然后唤醒等待队列的首位线程也就是线程2,让线程2进行CAS操作

独占式锁和共享式锁

  • 独占式:有且只有一个线程能获取到锁,如:ReentrantLock。
  • 共享式:可以多个线程同时获取到锁,如:CountDownLatch

公平锁和非公平锁

  • 公平锁:先到先得,线程通过排队的方式来获取锁
  • 非公平锁:后来的线程可能会率先获取到锁,非公平锁性能优于公平锁

【参考链接】:
1:由浅入深逐步讲解Java并发的半壁江山AQS
2:Java中的锁原理、锁优化、CAS、AQS详解
3:1.5w字,30图带你彻底掌握 AQS
4:【对线面试官】AQS&&ReentrantLock


评论
  目录