AQS源码阅读

模型参考自适应控制(MRAC):让PID参数动态优化 本文深入解析模型参考自适应控制(MRAC)技术,它通过实时调整PID参数,使控制系统能自动适应系统特性变化和外部干扰。文章详细介绍了MRAC的工作原理、数学基础,并提供了用C语言实现的实战代码示例,帮助工程师解决传统PID控制在非线性、时变系统中参数整定繁琐的难题。 阅读详情

简介

AQS 全程为
AbstractQueuedSynchronizer , 在 java.util.concurrent.locks包下的一个抽象类。

类的具体作用以及设计在开始类描述信息里面就有很好的表达

Provides a framework for implementing blocking locks and related
synchronizers (semaphores, events, etc) that rely on
first-in-first-out (FIFO) wait queues.  This class is designed to
be a useful basis for most kinds of synchronizers that rely on a
single atomic {@code int} value to represent state. Subclasses
must define the protected methods that change this state, and which
define what that state means in terms of this object being acquired
or released.  Given these, the other methods in this class carry
out all queuing and blocking mechanics. Subclasses can maintain
other state fields, but only the atomically updated {@code int}
value manipulated using methods {@link #getState}, {@link
#setState} and {@link #compareAndSetState} is tracked with respect
to synchronization.	
具体翻译为:
提供了实现阻塞锁和相关的框架,依赖于的同步器(信号量、事件等)。
先进先出 (FIFO) 等待队列。 这个类被设计为对于大多数依赖于单个原子 {@code int} 值来表示状态。 
子类必须定义更改此状态的受保护方法,以及根据正在获取的对象定义该状态的含义或释放。 鉴于这些,此类中的其他方法带有排除所有排队和阻塞机制。 子类可以维护其他状态字段,但只有原子更新的 {@code int}使用方法 {@link #getState}、{@link 操作的值#setState} 和 {@link #compareAndSetState} 被地跟踪、同步。

简单描述为:通过原子性的int值来标记同步状态,实现阻塞锁机制,基于FIFO队列来实现排队机制

AQS实现了两种模式,独占模式和共享模式,实现共享锁和排他锁

以独占锁为例,FIFO队列头节点获取到锁之后,其他节点会进入等待状态,释放锁之后,头节点的下一个节点会尝试获取锁,但是不一定成功(公平、非公平)。

LockSupport工具类

LockSupport 官方是这样描述的 Basic thread blocking primitives for creating locks and other , 翻译为 “基本线程阻塞原语,用于创建锁和其他”,可以理解为使用计算机原语来创建锁,底层实现为unsafe类,主要方法为pack(线程阻塞)与unpack(唤醒线程),源码如下:

// LockSupport设置阻塞分为两组,
	// 一组是不设置blocker的方法,另一组是设置blocker方法
	// JDK推荐为Thread设置blocker方便调试
	public static void park(Object blocker) {
        // 获取当前线程
        Thread t = Thread.currentThread();
        // blocker位线程内存当前偏移量,设置线程内存偏移量,
        setBlocker(t, blocker);
        // Unsafe包下的方法可以直接操作内存,设置线程阻塞
        U.park(false, 0L);
        // 线程唤醒后 blockers设置为空
        setBlocker(t, null);
    }
    public static void park() {
        // 线程阻塞,单纯唤醒,不会记录偏移量
        U.park(false, 0L);
    }
	// 与park基本相同,添加阻塞事件,自动唤醒
	public static void parkNanos(Object blocker, long nanos);
	public static void parkUntil(Object blocker, long deadline);
// unpark方法为unsafe.unpark方法,为C++实现,基于内存进行操作
	public static void unpark(Thread thread) {
        if (thread != null)
            U.unpark(thread);
    }

AQS内部结构

AQS类图

AQS的实现类为NofairSync(非公平)、FairSync(公平)两种。

内部类Node

static final class Node {
      // 共享
      static final Node SHARED = new Node();
      // 独占
      static final Node EXCLUSIVE = null;
      // 因为超时或者中断,节点会被设置为取消状态,被取消的节点时不会参与到竞争中的,他会一直保持取消状态不会转变为其他状态;
      static final int CANCELLED =  1;
      // 后继节点的线程状态处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点线程继续运行
      static final int SIGNAL    = -1;
      // 节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()后,该节点将会从等待队列中转移到同步队列中,加入到同步状态的获取中
      static final int CONDITION = -2;
      // 表示下一次共享式同步状态获取将会无条件地传播下去
      static final int PROPAGATE = -3;
      // 等待状态
      volatile int waitStatus;
      // 前驱结点
      volatile Node prev;
      // 后继节点
      volatile Node next;
      // Node封装当前线程
      volatile Thread thread;
      // 指向ConditionObject的下一个节点
      Node nextWaiter; 
    }

节点状态

  1. CANCELLED (1):当前线程因为超时或者中断被取消。这是一个终结态,也就是状态到此为止
  2. SIGNAL (-1):当前线程的后继线程被阻塞或者即将被阻塞,当前线程释放锁或者取消后需要唤醒后继线程。这个状态一般都是后继线程来设置前驱节点的
  3. CONDITION (-2):当前线程在condition队列中
  4. PROPAGATE (-3):用于将唤醒后继线程传递下去,这个状态的引入是为了完善和增强共享锁的唤醒机制。在一个节点成为头节点之前,是不会跃迁为此状态的

主要属性

/**
 * 等待队列的头节点, 赖加载
 * 除了初始化之外, 只能通过 setHead 方法来改变其值
 * 如果 head 不为 null, waitStatus 值就一定不会是 CANCELLED
 */
private transient volatile Node head;
 
/**
 * 等待队列的尾结点, 懒加载
 * 只能通过 enq 方法添加新节点时才会去改变尾结点
 */
private transient volatile Node tail;
 
/**
 * 同步器的状态
 * 以 ReentrantLock 为例, 0 表示可以获取到锁, 其他的正整数表示无法获取到锁
 */
private volatile int state;

AQS属性结构设计如下

具体方法

开放实现接口API,用于场景自定义:

方法

作用

boolean tryAcquire(int arg)

试获取独占锁

boolean tryRelease(int arg)

试释放独占锁

int tryAcquireShared(int arg)

试获取共享锁

boolean tryReleaseShared(int arg)

试释放共享锁

boolean isHeldExclusively()

当前线程是否获得了独占锁

AQS本身将同步状态的管理用模板方法模式都封装好了,以下列举了AQS中的一些模板方法

方法

描述

void acquire(int arg)

获取独占锁。会调用 tryAcquire 方法,如果未获取成功,则会进入同步队列等待

void acquireInterruptibly(int arg)

响应中断版本的 acquire

boolean tryAcquireNanos(int arg,long nanos)

响应中断+带超时版本的 acquire

void acquireShared(int arg)

获取共享锁。会调用 tryAcquireShared 方法

void acquireSharedInterruptibly(int arg)

响应中断版本的 acquireShared

boolean tryAcquireSharedNanos(int arg,long nanos)

响应中断+带超时版本的 acquireShared

boolean release(int arg)

释放独占锁

boolean releaseShared(int arg)

释放共享锁

Collection getQueuedThreads()

获取同步队列上的线程集合

源码层面上会对acquire、release、acquireShared 、releaseShared 进行详解

独占锁

// 获取独占锁  	
public final void acquire(int arg) {
        if (!tryAcquire(arg) && // 试获取独占锁,获取同步状态 
            // addWaiter,将线程封装成Node节点,添加到同步队列的尾部,acquireQueued,自旋等待,如果获取状态失败,挂起线程
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) 
            selfInterrupt(); // 线程中断
}

private Node addWaiter(Node mode) {
    //创建Node节点
    Node node = new Node(mode);

    for (;;) {
        // 当前队尾进行标记
        Node oldTail = tail;
        if (oldTail != null) {
            node.setPrevRelaxed(oldTail);
            // CAS操作放到队尾
            if (compareAndSetTail(oldTail, node)) {
                oldTail.next = node;
                return node;
            }
        } else {
            initializeSyncQueue();
        }
    }
}
// 将该线程加入等待队列的尾部,并标记为独占模式
final boolean acquireQueued(final Node node, int arg) {
    boolean interrupted = false;
    try {
        // 自旋,不断尝试当前线程获取锁,知道成功或者线程被打断
        for (;;) {
            // 获取前驱节点
            final Node p = node.predecessor();
            // 尝试获取锁
            if (p == head && tryAcquire(arg)) {
                // 成功之后将节点设置为新的头部节点
                setHead(node);
                p.next = null; // help GC
                return interrupted;
            }
            // 获取锁失败
            // 判断线程是否需要中断, 判断标准是前节点状态
            if (shouldParkAfterFailedAcquire(p, node))
                //挂起当前线程
                interrupted |= parkAndCheckInterrupt();
        }
    } catch (Throwable t) {
        cancelAcquire(node);
        if (interrupted)
            selfInterrupt();
        throw t;
    }
}
// 如果线程获取同步状态失败就要检查它的节点status,要保证prev = node.prev
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    // 前驱节点状态
    int ws = pred.waitStatus;
    // singal 表示前驱节点释放后会唤起当前线程,会继续等待,那么线程可以中断等待
    if (ws == Node.SIGNAL)
        return true;
    // 前驱节点不是Head节点,并且状态为CANCELLED,那么就需要剔除前置节点,向前遍历,直到找到合适的前置
    if (ws > 0) {
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {
        // 这种情况表示前驱节点的 ws = 0 或者 ws = PROPAGATE,那么设置前驱节点为singal,之后重新循环获取锁
        pred.compareAndSetWaitStatus(ws, Node.SIGNAL);
    }
    return false;
}

acquire方法为获取独占锁

  1. tryAcquire() 尝试直接去获取资源,如果成功则直接返回true,AQS中空方法,由实现类来实现,具体分析会在ReentrantLock中进行详细代码分析。
  2. addWaiter() 将该线程加入等待队列的尾部,并标记为独占模式
  3. acquireQueued()使线程阻塞在等待队列中获取资源,一直获取到资源后才返回。如果在整个等待过程中被中断过,则返回true,否则返回false。如果线程在等待过程中被中断过,它是不响应的。只是获取资源后才再进行自我中断selfInterrupt(),将中断补上
// 独占锁释放节点
public final boolean release(int arg) {
    // tryRelease由实现类具体实现
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            // 唤醒下一个节点
            unparkSuccessor(h);
        return true;
    }
    return false;
}

release方法通过tryRelease()实现了扩展性,来进行锁的重入设计,unparkSuccessor则自身实现,完成了下一个Node节点的唤醒

共享锁

public final void acquireShared(int arg) {
    // tryAcquireShared为抽象方法,由子类实现
    if (tryAcquireShared(arg) < 0)
        doAcquireShared(arg);
}	

private void doAcquireShared(int arg) {
    // 不断尝试从队列中获取共享锁,当成功获取到锁或者线程被打断时会成功退出循环,竞争锁失败的线程会被 park 直到被唤醒,唤醒之后会再次进入循环尝试去获取锁,不断的重复整个过程
    final Node node = addWaiter(Node.SHARED);
    boolean interrupted = false;
    try {
        for (;;) {
            final Node p = node.predecessor();
            if (p == head) {
                int r = tryAcquireShared(arg);
                if (r >= 0) {
                    setHeadAndPropagate(node, r);
                    p.next = null; // help GC
                    return;
                }
            }
            // 上面由详细解读
            if (shouldParkAfterFailedAcquire(p, node))
                interrupted |= parkAndCheckInterrupt();
        }
    } catch (Throwable t) {
        cancelAcquire(node);
        throw t;
    } finally {
        if (interrupted)
            selfInterrupt();
    }
}

// 释放共享锁
public final boolean releaseShared(int arg) {
    // 子类实现
    if (tryReleaseShared(arg)) {
        
        doReleaseShared();
        return true;
    }
    return false;
}
//当前节点调用
private void doReleaseShared() {
    for (;;) {
        Node h = head;
        if (h != null && h != tail) {
            int ws = h.waitStatus;
            // 如果头节点状态为SIGNAL, 表示可以去释放锁
            if (ws == Node.SIGNAL) {
                // 通过 cas 将 waitStatus 设为 0
                if (!h.compareAndSetWaitStatus(Node.SIGNAL, 0))
                    continue;            // loop to recheck cases
                // 线程唤醒
                unparkSuccessor(h);
            }
            else if (ws == 0 &&
                     !h.compareAndSetWaitStatus(0, Node.PROPAGATE))
                continue;                // loop on failed CAS
        }
        if (h == head)                   // loop if head changed
            break;
    }
}

关于独占锁和共享锁的异同

相同

1)获取锁前都会判断是否有权限,只有满足条件才可能获取到锁

2)未获取到锁的线程会创建新节点放入队列尾部

不同

1)独占锁只会释放头部后节点的线程,而共享锁会依次释放所有线程

2)独占锁存在非公平锁的情况,新的线程可能抢占队列中线程的锁,共享锁则不存在这种情况

扩展

AQS使用了模板方法的设计模式,以固定的方法进行调用,子类对其实现,方便扩展,后续会对具体实现类继续读源码。

基于fme和python-docx第三方库批量更新不动产调查表 最近应朋友需要批量更新在不动产成果中提交的各种word报表中的指定数据,根据初步的了解,我做了一个基于fme软件和python-docx第三方库进行一个批量的更新方案。 阅读详情

相关推荐

AD9361 Fast Lock实战:Python脚本自动生成Profile寄存器配置(附完整代码)

本文详细介绍了利用Python脚本实现AD9361 Fast Lock Profile寄存器自动化配置的实战方案。通过解析频率合成公式、VCO约束及查表机制,脚本能根据目标频率一键生成完整的16进制寄存器序列,大幅提升射频系统开发中多频点切换的效率和准确性,并支持CSV、JSON、C头文件等多种输出格式,便于与FPGA/嵌入式系统集成。

weixin_29194693的博客 475

AbstractQueuedSynchronizer(AQS)源码分析

AbstractQueuedSynchronizer(AQS)源码分析

ZHENHAOYOUNI的博客 237

o型圈沟槽设计_O型密封圈——详细选型过程及步骤

一、密封圈常用材料二、密封圈常用密封形式密封圈分为活塞密封,活塞杆密封,端面密封,旋转密封。三、O型密封圈的选型规则O型密封圈的尺寸图径向安装O型圈选型(静态和动态运动)活塞杆密封选择适当规格的O形圈时,应该保证其外径(d1+2*d2)至少等于或者大于沟槽外径d6;当选择的O形圈直径d1大于250 mm时, O形圈外径将不能超过沟槽外径的3%;当选择的O形圈直径d1小于250mm时, O形圈外径将...

weixin_39856630的博客 2万+

AQS的源码解析(自己的理解)

AQS的源码解析(自己的理解) 一:AQS的前置知识 AQS涉及到以下知识点:如不清楚可以去B站上看尚硅谷的大厂面试第二季juc 1.juc 2.LockSupper 3.模板模式 4.CAS 二:AQS是什么 字面意思: Abstract Queued Synchronizer(抽象的队列同步器) 实现原理: status成员变量+CLH队列变种 FIFO双向虚拟队列 简单流程理解: 通过控制stauts变量来表示锁的状态,0代表资源开发 1代表目前有人占用资源 默认初始化0,抢不到线程的资

weixin_43861634的博客 5306

weblogic 集群搭建,双机部署,相关问题记录

4.5.集群搭建1 参考网址https://wenku.baidu.com/view/76365129cd1755270722192e453610661ed95aa4.html IP地址 端口 角色 192.168.1.160 9001 AdminServer ...

zl386119974的专栏 1670

手把手教你用Isograph Reliability Workbench 14.0绘制可靠性方框图(RBD)

本文详细介绍了如何使用Isograph Reliability Workbench 14.0绘制可靠性方框图(RBD),从软件安装、界面设置到基础项目创建和高级功能应用,手把手指导工程师完成系统可靠性分析。通过实际案例演示,帮助用户掌握RBD建模技巧,提升系统可靠性评估效率。

weixin_26765287的博客 633

AQS学习与源码阅读

AQS全称抽象队列同步器,是一个用来构建锁和同步器的框架。可以用来构造应用广泛的同步器,比如SemaphoreFutureTask。

qq_45678095的博客 748

PyCharm安装PyQt5及工具(Qt Designer、PyUIC、PyRcc)详细教程来了

Qt是常用的用户界面设计工具,而在Python中则使用PyQt这一工具包,它是Python编程语言和Qt库的成功融合。这篇博文通过图文详细介绍在PyCharm中如何完整优雅地安装配置PyQt5的所有工具包,主要内容包括PyQt5、PyQt5-tools的依赖包安装和Qt Designer、PyUIC、PyRcc三个工具的设置。最后简单演示了PyQt5的调用方式及三个工具的使用方法。

Python966的博客 3万+

AQS源码阅读(JDK1.8)

一、简介 AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,是Java中众多锁以及并发工具的基础,其底层采用乐观锁,大量使用了CAS操作, 并且在冲突时,采用自旋方式重试,以实现轻量级和高效地获取锁。 AQS虽然被定义为抽象类,但事实上它并不包含任何抽象方法。这是因为AQS是被设计来支持多种用途的,如果定义抽象方法,则子类在继承时必须要覆写所有的抽象方法,这显然是不合理的。所以AQS将一些需要子类覆写的方法都设计成protect方法,将其默认实现为抛出UnsupportedOpera

小望没烦恼的博客 549

二维光子晶体禁带的遗传优化算法实现

二维光子晶体禁带的遗传优化算法MATLAB源代码 光子晶体中因周期性结构而存在的频率禁带称为光子禁带,光子禁带的存在是光子晶体具有广泛应用前景的重要原因。 禁带越大,可控光的频带也越宽,因此如何设计合适的晶体结构以获得大的光子禁带一直是研究和应用的重点与热点。 给大家讲解在平面波展开法的基础上,使用遗传算法寻找具有最大光子禁带的二维光子晶体结构。 %-------------------------------------------------------------------------- % Ph

m0_53407570的博客 583

解码器选型参数,结构原理,工艺与注意问题总结

解码器芯片(Decoder Chip)是电子设备中的一个重要组件,通常用于处理、解释和输出存储在某种编码格式中的数据或信号。本文对解码器的工作原理,结构特点,工艺流程,选型参数及设计注意事项进行总结。

fydar的博客 1172

AQS源码阅读感想

1.AQS核心原理 --AQS拥有变量state,通过CAS设定state得值是否成功判断是否获得锁,源码如下: compareAndSetState(c, nextc) protected final boolean compareAndSetState(int expect, int update) { return unsafe.compareAndSwapInt(thi...

idealemail的博客 172

【unity游戏开发入门到精通——UGUI】文本控件 —— TextetMeshPro新文本控件(TextMeshPro - Text(UI)和TextMeshPro - Text)

文本组件是UGUI中最常用的组件,它的作用是对文本数据进行处理并显示。UGUI的文本组件可以分两为种——Text旧文本控件、TextMeshPro新文本组件。本文主要是介绍TextMeshPro新文本控件,而TextMeshPro新文本控件又可以分为两种——TextMeshPro - Text(UI)和TextMeshPro - Text。TextMeshPro是Unity收购的一个第三方插件,现在已经自动内置到编辑器中,只要使用一次就会自动导入到工程。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3768

深入AQS源码阅读与强软弱虚4种引用以及ThreadLocal原理与源码

写在片头:声明,勿杠 首先简单说一下,这三次面试阿里并不是一次性去面的,实际上第一次面试时候还在大四,找的实习岗,不太清楚是什么部门,别问我为什么还记得面试题,有记录和复盘的习惯,再问就是杠。 个人背景不详细多说,学历双非本科,不是应届生,工作年限不长,技术不是大牛,但也非小白,面经分享是想给正面试的同行一些建议和鼓励,希望能够多多支持。 注意:下文内容中会提到一些简历模板、学习笔记、学习脑图、Java电子书籍和视频等,需要的私信我口令【成长】免费领取。 One:三顾茅庐,七面阿里,..

m0_63437643的博客 515

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JAVA劝退系列AQS源码阅读

这里写自定义目录标题新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 全新的界面设计 ,将会带来全新的写

烟花易冷 260

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

AQS源码阅读笔记(上)

场景信号传播机制关键缺陷结果理想状态顺序执行无竞争无工作正常无 PROPAGATE依赖单一状态检查并发释放导致信号丢失T2 永远阻塞有 PROPAGATE双重保障:1. PROPAGATE 标记2. 强制传播检查解决信号丢失所有线程正确唤醒。

agentoflyra的博客 1424

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

AQS源码阅读记录

AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)使用acquire/release(模板)方法对外提供功能。使用一个双向队列和指向队列两端的head/tail指针来实现线程的有序排队, ps:head指针指向的第一个node为傀儡node,不包含真实...

qq_37720278的博客 210

AQS源码阅读与理解

什么是AQS Provides a framework for implementing blocking locks and related synchronizers (semaphores, events, etc) that rely on first-in-first-out (FIFO) wait queues. This class is designed to be a useful basis for most kinds of synchronizers that rely on a

weixin_43180484的博客 262

AQS源码分析以及基于AQS之上的各种实现,带你阅读源码

AQS本质是一个双向队列,线程被包装成了一个个节点,节点在队列里面通过自旋一直尝试获取资源 AQS有两个队列 一个同步队列,一个条件队列 其实我感觉这个队列框架 和重量级锁的框架很像 有entrylist 代表着正在等待资源的线程队列,是双向的,entrylist叫等待队列,然后当获得资源的线程,使用了wait以后就进入了waitset,这里面的等待线程,就要等待一定条件后,然后被唤醒,再去entrylist的头部或者尾部进行争夺资源。waitset又叫条件等待队列,条件满足了,就被唤醒去等待队列。 这些

qq_45602114的博客 273

aqs,源码阅读,图解

AQS 是一个抽象类,提供了很多同步相关的默认实现,如线程入队、资源获取和释放等,子类可以继承 AQS 并通过重写一些关键方法来实现特定的同步器(如等)。Sync是内部类,用于具体实现不同同步器的业务逻辑,负责对锁的获取和释放等操作的实现。状态字段和 CAS:AQS 使用state字段表示同步状态,通过 CAS 操作来保证对共享资源状态的安全修改。等待队列:AQS 使用双向链表来管理等待队列,确保线程按照公平的顺序竞争资源。

qq_41577703的博客 177

从ReentrantLock到AQS源码阅读

ReentrantLock是使用AQS实现的一种可重入的独占锁,并且提供了公平和非公平两种策略。 ReentractLock的内部类Sync继承了AbstractQueuedSynchronizer抽象类,并且提供了两个内部类FairSync和NonfairSync(即公平锁与非公平锁的落地实现),而具体采用哪一种加锁策略则则是由ReentractLock的构造函数进行指定。 public ReentrantLock() { sync = new NonfairSync(); } public R

Nicholas_GUB的博客 702

阅读AQS -- AbstractQueuedSynchronizer源码

什么是AQS? 具体的类位于 : java.util.concurrent.locks.AbstractQueuedSynchronizer AQS是基于FIFO等待队列的,用来实现阻塞锁和相关同步机制的框架, 比如信号量(semaphroe), 事件(events), 可重入读写锁之类的,都是用这个实现的。其内部是使用原子int来表示状态的。子类需要覆盖其中的protected方法来实现同步机制。 AQS同时支持排他模式和共享模式。排他模式情况下,如果一个线程已经有锁了,其他线程是无法获取到锁的。共享模式

sparrowxin的博客 216
上一篇: RocketMQ 地推模式和拉模式有什么区别?
下一篇: MySQL事务的隔离级别与MVCC
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值