码迷,mamicode.com
首页 > 编程语言 > 详细

Java并发编程之AQS

时间:2018-11-19 21:40:30      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:rac   操作   protected   prot   安全   点线   expec   任务   node   

一、什么是AQS

  AQS(AbstractQueuedSynchronize:队列同步器)是用来构建锁或者其他同步组件的基础框架,很多同步类都是在它的基础上实现的,比如常用的ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore。

 

二、实现原理

  在AQS内部,定义了一个 volatile int state 变量来标识同步状态,通过改变state的状态来控制对共享资源的访问,根据不同的实现,state可以表示不同的状态,例如:在 ReentrantLock 中它表示拥有该锁的线程请求了多少次该锁;在 Semaphore 中表示剩余的许可数,在 FutureTask 中表示任务的状态(尚未开始、运行、完成和取消)。同时定义了一个 FIFO 队列维护争用资源时被阻塞的线程,当线程尝试获取锁时,如果锁已经被占用,那么该线程就会被构造成一个Node节点放到同步队列的尾部;队列的头节点是成功获取锁的节点,当头节点线程释放锁时,会唤醒后面的节点并释放当前头节点的引用。

  AQS主要通过继承的方式来使用,子类通过继承AQS并实现它的抽象方法来定义state变量的具体的访问规则,从而可以实现不同类型的同步组件。AQS定义了两种资源共享的方式:独占式和共享式。

  1. 独占式:同时只有一个线程能访问该共享资源。
  2. 共享式:多个线程可以同时访问该共享资源。

  AQS中可重写的方法如下:

  1. protected boolean tryAcquire(int arg):独占式获取同步状态,成功则返回true,失败则返回false。先查询同步状态并判断同步状态是否符合预期,然后再进行CAS设置同步状态。
  2. protected boolean tryRelease(int arg):独占式释放同步状态,成功则返回true,失败则返回false。等待获取同步状态的线程将有机会获取同步状态。
  3. protected int tryAcquireShared(int arg):共享式获取同步状态,返回大于等于0的值,表示成功,该值表示剩余可用资源数,小于0则表示获取失败。
  4. protected boolean tryReleaseShared(int arg):共享式释放同步状态,如果释放后允许唤醒后续等待结点返回true,否则返回false。
  5. protected boolean isHeldExclusively():当前同步器是否在独占模式下被线程占用,只在 AbstractQueuedSynchronizer.ConditionObject 的方法内进行内部调用,不使用Condition可以不重写。

 

  AQS自身没有实现任何同步接口,为了保证对state的访问修改操作是安全的,重写AQS指定的方法时,需要使用它提供的如下3个方法来访问或修改同步状态:

  1. getState():获取当前同步状态。
  2. setState(int newState):设置当前同步状态。
  3. compareAndSetState(int expect,int update):使用CAS设置当前状态,该方法能够保证状态设置的原子性。

 

  AQS是实现锁(同步组件)的关键,它在底层对同步状态管理、线程的排队、等待与唤醒做了实现,简化锁的实现。AQS是基于模板方法模式设计的,使用时需要继承AQS并重写对应的方法,再将其组合在同步组件中,当使用同步组件访问共享资源时,调用AQS提供的模板方法,然后模板方法会调用重写的方法。

 

Java并发编程之AQS

标签:rac   操作   protected   prot   安全   点线   expec   任务   node   

原文地址:https://www.cnblogs.com/Mr-XiaoLiu/p/9985408.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!