解锁Java并发编程的秘密武器!揭秘AQS,让你的代码从此告别‘锁’事烦恼,多线程同步不再是梦!

简介: 【8月更文挑战第25天】AbstractQueuedSynchronizer(AQS)是Java并发包中的核心组件,作为多种同步工具类(如ReentrantLock和CountDownLatch等)的基础。AQS通过维护一个表示同步状态的`state`变量和一个FIFO线程等待队列,提供了一种高效灵活的同步机制。它支持独占式和共享式两种资源访问模式。内部使用CLH锁队列管理等待线程,当线程尝试获取已持有的锁时,会被放入队列并阻塞,直至锁被释放。AQS的巧妙设计极大地丰富了Java并发编程的能力。

在Java的并发编程中,AbstractQueuedSynchronizer(简称AQS)是一个核心组件,它不仅是实现同步器的基础,也是并发包中多种锁(如ReentrantLock、CountDownLatch等)的底层实现。AQS通过其精巧的设计,为开发者提供了一种高效且灵活的同步机制。

AQS的核心概念
AQS是一个抽象类,全称为AbstractQueuedSynchronizer,它定义了一种基于FIFO(先进先出)队列的同步框架。AQS内部维护了一个volatile的state变量,用于表示同步状态。这个状态变量是AQS的核心,通过它来控制对共享资源的访问。当state为0时,表示没有线程持有锁;当state大于0时,表示有线程持有锁。

AQS支持两种资源共享模式:独占式和共享式。独占式模式下,每次只有一个线程能够持有锁,如ReentrantLock;而共享式模式下,允许多个线程同时访问共享资源,如ReentrantReadWriteLock的读锁部分。

AQS的内部结构
AQS内部使用了一个CLH(Craig, Landin, and Hagersten)队列来管理等待获取锁的线程。这个队列是一个双向链表,通过head和tail两个指针来维护队列的头部和尾部。每个节点(Node)代表一个等待获取锁的线程,节点中包含了线程引用、等待状态等信息。

AQS的工作原理
当一个线程尝试获取锁时,首先会检查state的值。如果state为0,表示当前没有线程持有锁,该线程将成功获取锁,并将state设置为1(或其他值,取决于具体实现)。如果state不为0,表示锁已被其他线程持有,当前线程将被放入等待队列中,并进入阻塞状态。

当持有锁的线程释放锁时,它会将state的值设置为0,并唤醒等待队列中的下一个线程。被唤醒的线程会再次尝试获取锁,如果成功,则继续执行;如果失败,则重新进入等待队列。

示例代码
下面是一个使用AQS实现简单互斥锁的示例代码:

java
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

class Mutex {
private final Sync sync = new Sync();

public void lock() {  
    sync.acquire(1);  
}  

public void unlock() {  
    sync.release(1);  
}  

private static class Sync extends AbstractQueuedSynchronizer {  
    @Override  
    protected boolean tryAcquire(int acquires) {  
        return compareAndSetState(0, 1);  
    }  

    @Override  
    protected boolean tryRelease(int releases) {  
        setState(0);  
        return true;  
    }  

    @Override  
    protected boolean isHeldExclusively() {  
        return getState() == 1;  
    }  
}  

}

// 使用示例
public class Main {
public static void main(String[] args) {
Mutex mutex = new Mutex();

    // 线程1尝试获取锁  
    new Thread(() -> {  
        mutex.lock();  
        try {  
            // 模拟任务执行  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } finally {  
            mutex.unlock();  
        }  
    }).start();  

    // 线程2尝试获取锁(将在线程1释放锁后获取)  
    new Thread(() -> {  
        mutex.lock();  
        try {  
            // 模拟任务执行  
            Thread.sleep(1000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } finally {  
            mutex.unlock();  
        }  
    }).start();  
}  

}
在这个示例中,我们定义了一个名为Mutex的互斥锁类,它内部使用了一个继承自AbstractQueuedSynchronizer的Sync类来实现锁的逻辑。通过重写tryAcquire、tryRelease和isHeldExclusively方法,我们实现了简单的锁获取和释放逻辑。

AQS以其简洁而强大的设计,为Java并发编程提供了坚实的基础。通过理解AQS的工作原理,我们可以更加深入地掌握Java并发编程的精髓。

相关文章
|
7月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
289 6
|
7月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
400 1
|
7月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
296 0
|
11月前
|
Java 数据库连接 API
2025 更新必看:Java 编程基础入门级超级完整版指南
本教程为2025更新版Java编程基础入门指南,涵盖开发环境搭建(SDKMAN!管理JDK、VS Code配置)、Java 17+新特性(文本块、Switch表达式增强、Record类)、面向对象编程(接口默认方法、抽象类与模板方法)、集合框架深度应用(Stream API高级操作、并发集合)、模式匹配与密封类等。还包括学生成绩管理系统实战项目,涉及Maven构建、Lombok简化代码、JDBC数据库操作及JavaFX界面开发。同时提供JUnit测试、日志框架使用技巧及进阶学习资源推荐,助你掌握Java核心技术并迈向高级开发。
946 5
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
|
安全 Java 调度
Java中的多线程编程入门
【10月更文挑战第29天】在Java的世界中,多线程就像是一场精心编排的交响乐。每个线程都是乐团中的一个乐手,他们各自演奏着自己的部分,却又和谐地共同完成整场演出。本文将带你走进Java多线程的世界,让你从零基础到能够编写基本的多线程程序。
196 1
|
Java 数据处理 开发者
Java多线程编程的艺术:从入门到精通####
【10月更文挑战第21天】 本文将深入探讨Java多线程编程的核心概念,通过生动实例和实用技巧,引导读者从基础认知迈向高效并发编程的殿堂。我们将一起揭开线程管理的神秘面纱,掌握同步机制的精髓,并学习如何在实际项目中灵活运用这些知识,以提升应用性能与响应速度。 ####
183 3
Java中的多线程编程:从入门到精通
本文将带你深入了解Java中的多线程编程。我们将从基础概念开始,逐步深入探讨线程的创建、启动、同步和通信等关键知识点。通过阅读本文,你将能够掌握Java多线程编程的基本技能,为进一步学习和应用打下坚实的基础。
|
算法 Java 开发者
Java 编程入门:从零到一的旅程
本文将带领读者开启Java编程之旅,从最基础的语法入手,逐步深入到面向对象的核心概念。通过实例代码演示,我们将一起探索如何定义类和对象、实现继承与多态,并解决常见的编程挑战。无论你是编程新手还是希望巩固基础的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
传感器 数据采集 监控
Java串口编程入门
Java串口编程入门

热门文章

最新文章