0%

AQS-1

文章字数:734,阅读全文大约需要2分钟

AbstractQueuedSynchronizer它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架。大部分同步工具内部都是使用AQS实现的。

一、LockSupport

jdk提供的线程阻塞、唤醒的工具。同步组件的基础

  • park开头的方法是用于阻塞线程的
  • unpark(Thread thread)方法是解除阻塞的

二、模板方法模式

  • 父类使用抽象类,定义若干动作,并且按顺序调用。
  • 子类实现具体动作
  • AQS里使用了模板方法模式

三、AQS中的抽象模板

3.1独占式获取锁

-accquire

  • acquireInterruptibly
  • tryAcquireNanos

    3.2共享式获取锁

  • acquireShared
  • acquireSharedInterruptibly
  • tryAcquireShareNanos

    3.3独占式释放锁

  • release

3.4共享式释放锁

  • releaseShared

3.5子类需要实现的过程方法

  • tryAcquire独占获取,内部判断哪个线程拿到了锁,然后setExclusiveOwnerThread(Thread.currentThread())设置当前线程占有锁,return true
  • tryRealease独占释放
  • tryAcquireShare共享获取
  • tryRealeaseShared共享释放
  • isHeldExclusively这个同步器释放处于独占模式(是否占用)

3.6同步状态

  • state:字段表示当前同步状态,使用volatile修饰。
  • getState:获取
  • setState:设置当前同步状态
  • compareAndSetState:使用CAS设置状态

3.6Condition

  • AQS提供了ConditionObject直接new返回就行了。
  • 内部维护了一个等待队列,保存等待的线程

四、AQS公平非共享内部实现

  • 内部使用一个先进先出的双向队列保存线程,保存了链表的头和尾
  • Node类就是线程节点
    节点类型waitState
  1. CANCELLED线程等待超时或者被中断,需要从队列移走
  2. SIGNAL后续的节点等待状态,当前节点通知后面节点运行
  3. CONDITION等待
  4. PEOPGATE共享状态,表示状态往后面传播
  5. 0初始状态
  • 竞争锁失败的线程被打包成Node放入同步队列尾部(CAS设置),如果上一个节点是头节点时会尝试获取锁,获取失败阻塞自己。成功会移除头节点,设置自身为头。Realsese方法会唤醒阻塞。
  • Condition中包含一个等待队列