[Java探索者之路] Java中的AbstractQueuedSynchronizer(AQS)简介

简介: [Java探索者之路] Java中的AbstractQueuedSynchronizer(AQS)简介

Java并发编程是一门复杂的艺术,而AbstractQueuedSynchronizer(AQS)是其中非常重要的一个组成部分。事实上,Java中许多同步器的实现,如ReentrantLock, Semaphore, CountDownLatch等,都依赖于AQS。在本文中,我们将详细介绍AQS的工作原理和如何使用AQS实现自己的同步器。


AQS的基本概念

AbstractQueuedSynchronizer简称AQS,是由Doug Lea创建的,它提供了一个基于FIFO队列的框架,用于实现阻塞锁和各种相关的同步器。



AQS的主要思想是,如果一个同步器(如一个锁或者一个信号量)在暂时无法满足当前线程对其的请求时,该同步器应该将当前线程加入到等待队列中,直到同步器处于可以满足该请求的状态。

AQS通过内部的一个FIFO队列(双向链表结构)来维护那些可能会阻塞的线程。

AQS通过内部的一个FIFO队列(双向链表结构)来维护那些可能会阻塞的线程。

如何使用AQS

要使用AQS,首先需要定义一个继承自AQS的自定义同步器。AQS提供了acquirerelease方法,但是这两个方法的具体实现需要由我们来提供。

例如,下面是一个简单的使用AQS实现的不可重入的互斥锁:

public class Mutex implements Lock {
    private static class Sync extends AbstractQueuedSynchronizer {
        protected boolean tryAcquire(int arg) {
            return compareAndSetState(0, 1);
        }

        protected boolean tryRelease(int arg) {
            if (state == 0) throw new IllegalMonitorStateException();
            setState(0);
            return true;
        }

        protected boolean isHeldExclusively() {
            return state == 1;
        }
    }

    private final Sync sync = new Sync();

    public void lock() { sync.acquire(1); }
    public boolean tryLock() { return sync.tryAcquire(1); }
    public void unlock() { sync.release(1); }
    public Condition newCondition() { throw new UnsupportedOperationException(); }
    public boolean isLocked() { return sync.isHeldExclusively(); }
    public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
}

其中,tryAcquiretryRelease就是我们需要提供的具体实现。tryAcquire在成功获取锁时返回true,否则返回false。tryRelease在成功释放锁时返回true,否则返回false。

结论

AbstractQueuedSynchronizer是Java提供的一种强大的并发工具,它的主要作用是将等待线程以FIFO的顺序排队。通过覆盖和实现AQS提供的模板方法,可以实现个性化的具备同步功能的组件。需要注意的是,正确地使用AQS需要对并发编程有深厚的理解,千万不能生搬硬套模板,否则可能带来意想不到的后果。



相关文章
|
5月前
|
人工智能 安全 Java
Go与Java泛型原理简介
本文介绍了Go与Java泛型的实现原理。Go通过单态化为不同类型生成函数副本,提升运行效率;而Java则采用类型擦除,将泛型转为Object类型处理,保持兼容性但牺牲部分类型安全。两种机制各有优劣,适用于不同场景。
187 24
|
5月前
|
人工智能 Java
java中static关键字简介
`static`关键字用于修饰类的成员变量和方法,使其属于类而非对象。静态成员可通过类名直接访问,无需实例化对象。静态方法只能访问静态成员,不能直接访问非静态成员或使用`this`关键字。此外,静态代码块在类首次加载时执行且仅执行一次,适用于初始化操作。
188 0
|
7月前
|
设计模式 人工智能 安全
AQS:Java 中悲观锁的底层实现机制
AQS(AbstractQueuedSynchronizer)是Java并发包中实现同步组件的基础工具,支持锁(如ReentrantLock、ReadWriteLock)和线程同步工具类(如CountDownLatch、Semaphore)等。Doug Lea设计AQS旨在抽象基础同步操作,简化同步组件构建。 使用AQS需实现`tryAcquire(int arg)`和`tryRelease(int arg)`方法以获取和释放资源,共享模式还需实现`tryAcquireShared(int arg)`和`tryReleaseShared(int arg)`。
395 32
AQS:Java 中悲观锁的底层实现机制
|
8月前
|
Java
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
前言 主播觉得,AQS的原理,就是通过这2个队列的协助,实现核心功能,同步队列(CLH队列)和条件队列(Condition队列)。 同步队列(CLH队列) 作用:管理需要获...
160 18
【源码】【Java并发】【AQS】从ReentrantLock、Semaphore、CutDownLunch、CyclicBarrier看AQS源码
|
9月前
|
设计模式 存储 安全
【Java并发】【AQS】适合初学者体质的AQS入门
AQS这是灰常重要的哈,很多JUC下的框架的核心,那都是我们的AQS,所以这里,我们直接开始先研究AQS。 那说到研究AQS,那我们应该,使用开始说起🤓 入门 什么是AQS? AQS(Abst
176 8
【Java并发】【AQS】适合初学者体质的AQS入门
|
9月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
406 29
JVM简介—1.Java内存区域
|
9月前
|
Java Linux API
课时3:Java简介(Java主要特点)
本文介绍了Java的主要特点及其运行机制。Java结合了编译型和解释型语言的优点,通过Java虚拟机(JVM)实现跨平台移植,简化了不同操作系统间的开发流程。Java的特点包括可移植性、简单易用、支持多线程编程、自动垃圾收集和面向对象编程。随着硬件技术的发展,Java的性能问题已大大改善,成为行业标准之一,广泛应用于各种商用平台开发。
308 1
|
9月前
|
开发框架 移动开发 Java
课时2:Java简介(Java发展概述)
课时2:Java简介(Java发展概述) 摘要: 1. Java基础知识:介绍Java作为编程语言及其思想。 2. Java的发展历史:从1991年GREEN项目到1995年正式推出,历经网景公司、HotJava浏览器等关键节点。 3. Java的版本信息:涵盖从JDK 1.0到JDK 1.8的主要版本及特性,如Lambda表达式和模块化支持。
195 0
|
9月前
|
存储 Java C语言
课时11:Java数据类型简介
本文介绍了Java中的数据类型划分,主要分为基本数据类型和引用数据类型。基本数据类型包括数值型(整型、浮点型)、布尔型和字符型,每种类型有固定的默认值和存储范围。引用数据类型涉及内存使用,如数组、类和接口,默认值为Null。文中还提供了不同类型的选择原则,帮助开发者在实际编程中合理选用数据类型。
122 0
|
9月前
|
Oracle Java Unix
课时1:认识Java(Java发展简介)
课时1:认识Java(Java发展简介)。主讲人李兴华介绍了Java的起源、发展历程及其广泛应用。Java由Sun公司开发,最初为嵌入式系统设计,后演变为三大方向:Java SE、Java ME和Java EE。尽管面临版权争议等挑战,Java仍是最流行的编程语言之一,广泛应用于大型企业及互联网平台开发。
122 0