JUC的AQS的第一部分

JUC框架 源码解析系列文章目录 JDK8 前言 笔者在接下来这段时间将对JUC框架内的重点内容进行深度解析,由于内容颇多,需要分成多篇文章,所以在这里列一个目录,方便大家翻阅。 目录 JUC框架的基础是CAS和自旋,而CAS则是利用Unsafe类提供的CAS操作,而原子类则依靠于CAS和自旋。下面几篇文章从源码分析JUC框架内的几个重要的原子类。 JUC AtomicInteger源码解析 JDK8 JUC AtomicIntegerArray源码解析 JDK8 JUC AtomicStampedReference源码解析 JDK8 AQS(A 阅读详情

部分摘抄自

https://www.cnblogs.com/daydaynobug/p/6752837.html

概述

以JUC locks包中的ReentrantLock为例,其内部有一个对象,并实现了该对象的类是ReentrantLock类中的一个内部类。这是JUC lock的典型实现。AbstractQueuedSynchronizer是设计模式中的模版方法,提供了典型的锁的行为。

private final Sync sync;
abstract static class Sync extends AbstractQueuedSynchronizer {
...
}

AbstractQueuedSynchronizer这个类虽然号称Abstract,但是已经拥有一个完整的锁的实现。

##CLH队列
多线程争用资源时会进入此队列
这里写图片描述

以ReentrantLock为例,state初始化为0,表示未锁定状态。A线程lock()时,会调用tryAcquire()独占该锁并将state+1。此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,其它线程才有机会获取该锁。当然,释放锁之前,A线程自己是可以重复获取此锁的(state会累加),这就是可重入的概念。但要注意,获取多少次就要释放多么次,这样才能保证state是能回到零态的。

private volatile int state;

一个节点表示一个线程,它保存着线程的引用(thread)、状态(waitStatus)、前驱节点(prev)、后继节点(next)
NODE节点的代码段如下

        /**
         * Status field, taking on only the values:
         *   SIGNAL:     它的下一个节点接下来需要唤醒(unpack)的线程(-1)
         *   CANCELLED:  因为线程被中断或者等待超市,节点请求锁处于被取消状态。是节点的终态。(1)节点在处于CANCELLED状态时会被删除
         *               
         *   CONDITION:  This node is currently on a condition queue.
         *               It will not be used as a sync queue node
         *               until transferred, at which time the status
         *               will be set to 0. (Use of this value here has
         *               nothing to do with the other uses of the
         *               field, but simplifies mechanics.)(-1)
         *   PROPAGATE:  A releaseShared should be propagated to other
         *               nodes. This is set (for head node only) in
         *               doReleaseShared to ensure propagation
         *               continues, even if other operations have
         *               since intervened.(-3)
         *   0:          表示当前节点正等待在队列中
         *
         * The values are arranged numerically to simplify use.
         * Non-negative values mean that a node doesn't need to
         * signal. So, most code doesn't need to check for particular
         * values, just for sign.
         *
         * The field is initialized to 0 for normal sync nodes, and
         * CONDITION for condition nodes.  It is modified using CAS
         * (or when possible, unconditional volatile writes).
         */
        volatile int waitStatus;

CLH队列是一个双向队列。

AQS

AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。

sHeldExclusively()//该线程是否正在独占资源。只有用到condition才需要去实现它。
tryAcquire(int)//独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int)//独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int)//共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int)//共享方式。尝试释放资源,成功则返回true,失败则返回false。

线程的中断机制

如果一个线程处于了阻塞状态(如线程调用了thread.sleep、thread.join、thread.wait、1.5中的condition.await、以及可中断的通道上的 I/O 操作方法后可进入阻塞状态),则在线程在检查中断标示时如果发现中断标示为true,则会在这些阻塞方法(sleep、join、wait、1.5中的condition.await及可中断的通道上的 I/O 操作方法)调用处抛出InterruptedException异常,并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。抛出异常是为了线程从阻塞状态醒过来,并在结束线程前让程序员有足够的时间来处理中断请求。

aquire流程

这里写图片描述

    //acquire算法是不许覆盖的,所以所有子类都要使用这个方法
    public final void acquire(int arg) {
        if (!tryAcquire(arg) &&//tryAcquire必须在子类实现,否则就会抛出UnsupportedOperationException异常
            //EXCLUSIVE是Node中的一个类字段,初始固定为null
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            //清除中断标志位
            selfInterrupt();
    }
    
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;
        if (pred != null) {//CLH已经进行初始化的状态
            node.prev = pred;
            //CAS操作追加到队尾
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);//CLH还没进行初始化的状态
        return node;
    }

	final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
			    //检查自己是不是队列第二位且拿到号
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }

    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);//使用Unsafe机制暂停线程,使用当前对象作为blocker
        return Thread.interrupted();
    }

    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
            /*
             * This node has already set status asking a release
             * to signal it, so it can safely park.
             */
            return true;
        if (ws > 0) {
			//ws大于0表示pred节点已经被取消。删除之。
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            /*
             * waitStatus must be 0 or PROPAGATE.  Indicate that we
             * need a signal, but don't park yet.  Caller will need to
             * retry to make sure it cannot acquire before parking.
             */
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }

Release流程

    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
    private void unparkSuccessor(Node node) {
        /*
         * If status is negative (i.e., possibly needing signal) try
         * to clear in anticipation of signalling.  It is OK if this
         * fails or if status is changed by waiting thread.
         */
        int ws = node.waitStatus;
        if (ws < 0)
	        //将node中的WaitStatus原子性的置为0
            compareAndSetWaitStatus(node, ws, 0);

        /*
         * Thread to unpark is held in successor, which is normally
         * just the next node.  But if cancelled or apparently null,
         * traverse backwards from tail to find the actual
         * non-cancelled successor.
         */
        Node s = node.next;
        if (s == null || s.waitStatus > 0) {
            s = null;
            for (Node t = tail; t != null && t != node; t = t.prev)
                if (t.waitStatus <= 0)
                    s = t;
        }
        if (s != null)
            LockSupport.unpark(s.thread);
    }
	//CAS操作也是采用unsafe包实现的
    private static final boolean compareAndSetWaitStatus(Node node,
                                                         int expect,
                                                         int update) {
        return unsafe.compareAndSwapInt(node, waitStatusOffset,
                                        expect, update);
    }

ReentrantLock为例

ReentrantLock内部的Sync进一步实现AbstractQueuedSynchronizer的部分留空的逻辑。但是Sync类也是抽象类,FairSync,NonfairSync最终实现了完整逻辑。

Sync类实现了tryRelease的逻辑。就是尝试给state减去releases值,一般为1。

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

NonfairSync和FairSync的主要区别就是在tryAcquire这个方法上。他们也最终提供了lock方法
首先看公平版本

        final void lock() {
            acquire(1);
        }


        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            //如果当前state为0,检查下队列里是否有节点,如果没有,赶紧抢占
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //如果发现虽然state不是0,但是就是占有锁的线程就是自己,从容给state+1
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;//一般为1
                if (nextc < 0)//最多支持的锁的数量不能超过int的最大值
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            //抢占失败,乖乖去排队
            return false;
        }

再来对比不公平版本

		
        final void lock() {
		    //先抢一波
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            //差别就在于不检查队列里是否有其他节点,我就是要抢,管你有没有人排队,抢第二波
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) 
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            //仍然抢占失败,乖乖去排队
            return false;
        }

有timeout的实现

    //这是final的方法,子类不能覆盖,是提供给子类的标准模版
    public final boolean tryAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        return tryAcquire(arg) ||
            doAcquireNanos(arg, nanosTimeout);
    }

    private boolean doAcquireNanos(int arg, long nanosTimeout)
            throws InterruptedException {
        if (nanosTimeout <= 0L)
            return false;
        //计算自己的deadline
        final long deadline = System.nanoTime() + nanosTimeout;
        final Node node = addWaiter(Node.EXCLUSIVE);
        boolean failed = true;
        try {
            for (;;) {//进入自旋过程
                final Node p = node.predecessor();
                //检查自己是不是老二而且拿到号。
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return true;
                }
                //计算当前到deadline的时间
                nanosTimeout = deadline - System.nanoTime();
                if (nanosTimeout <= 0L)
                    return false;
                //如果当前时间到dealine的时间超过了spinForTimeoutThreshold,那就不自旋了,直接park
                if (shouldParkAfterFailedAcquire(p, node) &&
                    nanosTimeout > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanosTimeout);
                //检查线程是否被打断
                if (Thread.interrupted())
                    throw new InterruptedException();
            }
        //java基础:finally语句是在return执行之后,return返回之前执行的
        } finally {
            //检查标志位,取消节点
            if (failed)
                cancelAcquire(node);
        }
    }

共享锁的实现

这篇文章太长了,请看续集【JUC之AQS:共享锁部分】

JUC 之 Condition 使用 + 原理分析 多线程笔记(十七):前言 在多线程笔记(十):wait()/notify()/notifyAll() 的用法中,我们有介绍了 wait()、notify()方法的使用。 在使用 Lock 锁之前,我们使用最多的同步方式就是 synchronized 关键字来实现同步方式了。然后配合 Object 的 wait()、notify()、notifyAll()方法,来实现线程的等待、唤醒... 阅读详情

相关推荐

【Java多线程】JUC之深入队列同步器(AQS)(二)ConditionObject源码解析

- ​ AQS除了`同步队列`之外,还存在`Condition队列(等待队列,也可称为条件队列)`,也是一个`FIFO的`单向队列 。该队列是Condition对象实现`线程等待/通知功能`的核心。**但条件队列不是必须的,只有当使用Condition时,才会存在此队列。并且可能会有`多个`条件队列。** - ConditionObject是AQS的**成员内部类** ,可以调用AQS同步器的`所有成员变量和方法`。内部变量`firstWaiter、lastWaiter`分别表示等待条件的`第一个节

墩墩分墩 1244

【JUC】AQS(AbstractQueuedSynchronizer, 抽象队列同步器)

本文档概述了AQS(Abstract Queued Synchronizer)的基础理论知识及其在Java并发控制中的核心地位。AQS作为Java并发库(JUC)的基石,通过一个抽象的FIFO队列和一个表示同步状态的int变量,为锁和其他同步组件提供了一个通用的实现框架。文档解释了公平锁与非公平锁的区别、可重入锁的概念、自旋思想以及LockSupport的作用,并介绍了AQS内部的CLH队列变体和关键数据结构——Node节点,深入浅出地剖析了AQS的工作原理。

我只管埋头前行,剩下的交给时间。 1523

千呼万唤始出来:JUC灵魂AQS终于来了

涉及AQS核心方法、lock、unlock、CountDownLatch、await、signal几个重要组件的底层讲解

sowhat 9040

JUC并发包详解AQS同步队列

在JUC并发包中,AQS为其最关键的作用,全称为abstractQueuedSynchroinzed同步器,为信号量semaphore、同步锁的基础抽象类。其中内部主要有二大块state共享资源,通过并发操作state修改改值为1,如果修改成功则表示获得锁。FIFO队列该队列为CLH队列的变形队列,通过引入双向队列,采取自旋加堵塞的方式提高性能,其中核心为head节点、tail节点。

路漫漫其修远兮 吾将上下而求索 653

华为昇腾 910B 实战:DeepSeek-R1 蒸馏模型高效部署与性能调优全解析

本文详细解析了在华为昇腾910B硬件平台上高效部署DeepSeek-R1蒸馏系列模型(14B/32B版本)的完整实战流程。内容涵盖从MindIE环境搭建、镜像获取、模型准备,到服务配置、内存参数调优、性能测试及常见问题排查,为开发者提供了基于昇腾910B进行大模型部署与优化的全链路指南。

weixin_28235513的博客 211

Claude Code vs Codex实战对比:哪个更适合你的Next.js项目?(含真实案例)

本文通过两个真实的Next.js项目案例,深度对比了Claude Code与Codex在UI实现和业务逻辑构建中的表现。Claude Code在代码质量、设计还原度和架构完整性方面优势明显,适合对可维护性要求高的生产级项目;而Codex则以快速响应和低成本见长,更适合原型开发或内部工具。文章提供了基于项目类型、团队能力和成本效益的详细选择策略。

weixin_29201859的博客 810

一篇文章讲清楚 JUC 核心的 AQS的原理!

AQS全称,(抽象的队列同步器)是阻塞式锁和相关同步器工具的核心 · 父框架。Queued(队列)对应着没有抢到锁的线程处理规则。这个框架十分重要,其他的并发工具都要依赖于AQS。整体是通过一个抽象的FIFO队列来完成资源获取队列的排队工作,并通过一个int 类变量表示锁的状态。官方解释:提供一个框架,用于实现依赖先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)。此类被设计为大多数类型的同步器的有用基础,这些同步器依赖于单个原子int值来表示状态。

weixin_52834606的博客 1170

ML307A模组通过MQTT协议接入OneNET平台的AT指令全解析

本文详细解析了ML307A模组通过MQTT协议接入OneNET平台的完整AT指令流程。从平台侧的产品创建、设备添加,到核心难点连接密钥的计算方法,再到模组侧的基础网络附着、MQTT连接配置、数据收发及调试排错,提供了手把手的实战指南,帮助开发者快速实现物联网设备上云。

weixin_29240711的博客 495

JUC并发编程之AQS原理

AQS全称是 AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架子类主要实现这样一些方法 (默认抛出UnsupportedOperationException)获取锁的姿势释放锁的姿势。讲解AQS的原理

m0_55993923的博客 761

Java utgard连接OPC问题记录

怎么开启是个问题, 是在引入openscada的jar包里的Sever类中修改,这就犯难了, 其实没必要, 只要在自己项目下创建与openscada中Server类相同的路径,并复制Server过去改就行了, 项目会优先使用本地类,像下面这样。奇迹发生了,0x00000005解决. 注: 我的安全补丁编码跟网上查到的并不一样, 所以最初没有删,后来全都删了就好了,这个编码规则咱也不知道.安全日志中记录用户登录行为, OPC通信需要使用Windows系统用户进行登录, 如果用户名密码错误这里会有相关记录.

wangxin1949的博客 2841

统信UOS丨开机无法进入系统 无法打开控制台访问权限,root账号被锁定(cannot open access to console, the root account is locked)

步骤四:分别打开文件发现Roota下的fstab就是我们要找的文件,打开查看Roota的属性发现其为挂载的磁盘nvme0n1p3。步骤三:按Win+E打开文件管理器在分区中查找/etc/fstab文件,发现Roota和Rootb下都有该文件。步骤二:按键盘Ctrl+Alt+F4,进入终端控制台,如下图所示输入startx回车,进入桌面。步骤一:找到UOS系统安装的U盘,选择U盘启动进入安装界面,如下图所示。步骤七:关机,拔出U盘,启动电脑,OK,问题解决。

Reyn_观极 1万+

JUC锁核心类AQS解析

JUC锁核心类AQS解析 简介 AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore等,它使用一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作,它是我们实现大部分同步需求的基础。 AQS的主要使用方式是继承,子类通过继承同步器并实现它的抽象方法来管理同步状态,AQS的涉及是基于模板方法模式的,它内部定义好了所有跟锁相关的底层操作细节与算法骨架,只保留了几个方法让子类重写,子类

weixin_45563088的博客 1247

<PLC><西门子><工控>西门子博图V18中使用SCL语言编写一个CRC16-modbus校验程序

西门子官方对于SCL语言的介绍如下:SCL 编程语言SCL 编程语言SCL(Structured Control Language,结构化控制语言)是一种基于 PASCAL 的高级编程语言。这种语言基于标准DIN EN 61131-3(国际标准为 IEC 1131-3)。根据该标准,可对用于可编程逻辑控制器的编程语言进行标准化。SCL 编程语言实现了该标准中定义的 ST 语言 (结构化文本) 的PLCopen 初级水平。语言元素。

用沸腾的热血,支付我们的人生吧! 1439

JUC核心控件AQS源码解析第一部分(简介、成员属性、非公平独占锁加锁和解锁流程)

AQS简介 AQS是其他同步控件的基础,例如ReentrantLock,CountDownLatch,CylicBarrier,这几个类都是继承AQS然后重写AQS的模板方法实现同步的 AQS维护了一个state控制加锁解锁的状态变量,一个双向链表表示等待获取锁的线程 成员属性 内部类Node,封装了线程 static final class Node { //表示当前节点是共享状态 static final Node SHARED = new Node();

weixin_43478710的博客 372

threadX的USBX的初始化和解初始化的分析。

tx_application_define的最后会使用tx_byte_pool_create创建usb线程的内存空间“ux_device_app_byte_pool”,再创建usb线程,也就是执行。主要就是创建了线程,也就是第3个参数app_ux_device_thread_entry,这个参数内是MX_USB_Device_Init,也就是USB底层初始化。进来的参数只有1个,是memory_ptr,这个就是创建的usb线程空间“ux_device_app_byte_pool”

qq_31885403的博客 647

innovus:set_clock_latency与insertion_delay

当1ns clock latency设置在capture上,在report_timing报告中体现在other end arrival time以及capture clock path的Arrival Time上。因为-1ns的insertion delay存在,所以skew group报告中显示的Arrival (ns)是减1ns的结果,即1.819-1=0.819 ns。CTS阶段create_ccopt_clock_tree_spec之后,spec中会产生对应的insertion_delay命令。

m0_61544122的博客 1623

AQS源码解析——ReentrantLock独占锁篇

CLH 队列(Craig, Landin, and Hagersten 队列)是一种用于实现自旋锁的队列数据结构,基于链表实现,旨在解决自旋锁中的一些缺点,比如对缓存一致性问题、内存系统的高度竞争等。而非公平锁,线程获取锁的顺序不确定,可能后来线程有限获取锁,排在队头的线程不一定能争抢到锁资源。实现公平的逻辑就是hasQueuedPredecessors方法,简单来说这个方法就是去找阻塞队列里有没有线程正在排队,如果有,那么不好意思,乖乖去排队吧。,则会启用公平策略,即等待时间最长的线程会优先获取锁。

weixin_44210373的博客 1595

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

AQS源码解析——BlockingQueue阻塞队列篇

提供了阻塞操作,意味着当队列为空时,尝试获取元素的操作会被阻塞,直到有元素可用;当队列已满时,尝试放入元素的操作会被阻塞,直到有空间可用。是Java juc包的一部分,它是一个支持阻塞操作的队列。可以实现生产者-消费者模式,在队列未空或队列已满是阻塞线程,从而实现线程之间的同步和协作。这个方法会将node节点插入到CLH上,如果返回false说明当前node被其他线程在转移,获取下一个接着转移,直到整个队列转移完成。提供等待唤醒机制,实现线程之间的协调和同步。核心源码,源码很绕,需要多思考!

weixin_44210373的博客 2318

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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

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

【JUC】三十、什么是AQS

AQS,即AbstractQueuedSynchronizer,抽象的队列同步器。AQS是JUC的基石,好比JVM之于Java。AQS是用来实现锁或者其它同步器组件的公共基础部分的抽象实现, 是重量级基础框架及整个JUC体系的基石,主要用于解决锁分配给"谁"的问题。AbstractOwnableSynchronizer(下面两兄弟的父类)AbstractQueuedSynchronizer:简称AQS,since1.5三者都是抽象类。

llg___的博客 1775

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

7. Java JUC源码分析系列笔记-AQS

thead1获取锁成功,执行业务逻辑thread2获取失败,进入CLH队尾,不停自旋检查如果前一个节点的状态是signal,则进入阻塞;否则一直自旋直到获取锁成功thread1释放锁,唤醒下一个节点thead2从阻塞中醒来,获取锁成功,执行业务逻辑。

ThinkerQAQ 2270

JUC之AQS

AQS(AbstractQueuedSynchronizer)是Java并发包的核心框架,用于构建锁和同步器。其核心设计包括:1)volatile int状态变量管理同步状态;2)CLH变体队列管理等待线程;3)模板方法模式,子类实现关键方法如tryAcquire。AQS支持独占(如ReentrantLock)和共享(如Semaphore)模式,通过state变量和FIFO队列实现高效线程同步。

编程技术圈 1338

深入解析Java多线程与并发编程(五)(JUC显示锁、AQS抽象同步器以及JUC高并发容器)

本文介绍了JUC显式锁、AQS抽象同步器以及JUC高并发容器的基本概念。JUC显式锁是一种灵活的Java实现锁,支持多种锁操作,如可轮询、定时、可中断等。显式锁的核心接口是Lock,其主要实现类为ReentrantLock,具有可重入、独占等特性。显式锁可分为可重入锁、不可重入锁、悲观锁、乐观锁、公平锁、非公平锁、可中断锁、不可中断锁、共享锁和独占锁等类型。悲观锁适用于写多读少场景,而乐观锁适用于读多写少场景。公平锁保障线程按顺序获取锁,非公平锁则不保证。可中断锁允许在抢占过程中中断,而不可中断锁则不允许。

wxchyy的博客 1416

JUC基础(三)—— Lock锁 及 AQS

我们第一章提到了JUC的几大组成部分,其中就包含了“锁”,实际上Lock锁在业务上的使用频率恐怕是最高的,它弥补了很多synchronized关键字无法顾及的场景,灵活而强大。今天我们就来看一看这个强大的Lock以及它的核心类

战斧的博客 3460

JUC并发编程AQS源码解读

JUC个人学习笔记

西岭千秋雪的博客 1209

JUC-AQS原理篇

AQS全称是AbstractQueuedSynchronizer,这个抽象类是java并发包java.util.concurrent.locks(JUC)中的核心,它是JUC包下面多个组件的底层实现。比如CountDownLatch,Semaphore,CyclicBarrier,ReentrantLock,ReentrantReadWriteLock,ThreadPoolExecutor等的底层实现都用到了AQS。简单来讲,AQS是一个抽象类,这些组件的共性功能,它实现了,差异化的功能,它提供接口,由具体

zqj1172102457的博客 655
上一篇: JUC中多线程的集合——ConcurrentHashMap
下一篇: JUC之各种锁的使用:CountDownLatch,CyclicBarrier,ReadWriteLock,Semaphore
define_us
博客等级 码龄14年 157粉丝 531原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值