专业的编程技术博客社区

网站首页 > 博客文章 正文

AbstractQueuedSynchronizer 队列同步器

baijin 2024-10-16 07:36:13 博客文章 10 ℃ 0 评论

AQS大致结构

整个AQS分为两个队列,一个同步队列(双向),一个条件队列(也叫等待队列,单向)。只有同步队列中的节点才能获取锁。前面两篇独占锁共享锁文章中提到的加入队列就是同步队列。条件队列中所谓的唤醒是把节点从条件队列移到同步队列,让节点有机会去获取锁。

AQS原理简介

AQS的实现依赖内部的同步队列(FIFO双向队列),如果当前线程获取同步状态失败,AQS会将该线程以及等待状态等信息构造成一个Node,将其加入同步队列的尾部,同时阻塞当前线程(

入队的线程将会通过自旋的方式获取同步状态,若在有限次的尝试后,仍未获取成功,线程则会被LockSupport.park方法阻塞住。),当同步状态释放时,唤醒队列的头节点。

 private transient volatile Node head;
 
 private transient volatile Node tail;
 private volatile int state;

上面提到的同步状态就是这个int型的变量state. head和tail分别是同步队列的头结点和尾结点。假设state=0表示同步状态可用(如果用于锁,则表示锁可用),state=1表示同步状态已被占用(锁被占用)。

下面将介绍三组重要的方法,通过使用这三组方法即可实现一个同步组件。

第一组方法是用于访问/设置同步状态的,如下:

第二组方需要由同步组件覆写。如下:

第三组方法是一组模板方法,同步组件可直接调用。如下:

上述方法可以归结为两类:一类是独占式获取和释放共享状态,另一类是共享式获取和释放同步状态。

独占式获取同步状态流程图如下:


最后提下线程里相关方法的比较

condition对象只能用于独占模式,每一个创建的ConditionObject都维持这各自的一个单向的等待队列,但是每个ConditionObject都共享一个AQS的FIFO同步队列,就绪状态应该是指唤醒节点

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表