Java 中 AQS 的几大经典实现示例详解

 更新时间:2025年09月26日 08:58:16   作者:Techie峰  
AQS是Java并发包中的一个核心基础类,用于构建高效、可扩展的锁和同步器,以下是Java中常见的基于AQS的实现类,每个实现都针对特定场景提供了同步功能,我会逐一介绍它们的主要用途、特点,并提供一个简单的代码示例,感兴趣的朋友一起看看吧

AbstractQueuedSynchronizer(AQS)是Java并发包(java.util.concurrent.locks)中的一个核心基础类,用于构建高效、可扩展的锁和同步器。它通过一个FIFO队列管理线程的排队和唤醒机制,简化了同步器的开发。以下是Java中常见的基于AQS的实现类,每个实现都针对特定场景提供了同步功能。我会逐一介绍它们的主要用途、特点,并提供一个简单的代码示例。

1.ReentrantLock(可重入锁)

  • 用途:实现互斥锁,支持可重入性(同一线程可多次获取锁),避免死锁。常用于替代synchronized关键字,提供更灵活的锁控制(如超时、中断)。
  • 特点:基于AQS的独占模式(exclusive mode),内部维护一个状态变量记录锁的持有次数。
  • 代码示例
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();
    public void safeMethod() {
        lock.lock(); // 获取锁
        try {
            // 临界区代码
            System.out.println("线程安全操作");
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}

2.ReentrantReadWriteLock(可重入读写锁)

  • 用途:实现读写分离的锁,允许多个线程同时读共享资源,但写操作时独占锁。适用于读多写少的场景,提升并发性能。
  • 特点:基于AQS的共享-独占混合模式,内部使用两个AQS实例(一个用于读锁,一个用于写锁)。
  • 代码示例
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private int sharedData = 0;
    public void readData() {
        rwLock.readLock().lock(); // 获取读锁
        try {
            System.out.println("读取数据: " + sharedData);
        } finally {
            rwLock.readLock().unlock(); // 释放读锁
        }
    }
    public void writeData(int value) {
        rwLock.writeLock().lock(); // 获取写锁
        try {
            sharedData = value;
            System.out.println("写入数据: " + value);
        } finally {
            rwLock.writeLock().unlock(); // 释放写锁
        }
    }
}

3.Semaphore(信号量)

  • 用途:控制对共享资源的并发访问线程数,通过许可证(permits)机制实现限流。常用于资源池(如数据库连接池)。
  • 特点:基于AQS的共享模式(shared mode),状态变量表示可用许可证数量。

代码示例

import java.util.concurrent.Semaphore;
public class SemaphoreExample {
    private final Semaphore semaphore = new Semaphore(3); // 允许最多3个线程同时访问
    public void accessResource() throws InterruptedException {
        semaphore.acquire(); // 获取许可证
        try {
            // 访问共享资源
            System.out.println("资源被占用中...");
            Thread.sleep(1000); // 模拟操作
        } finally {
            semaphore.release(); // 释放许可证
        }
    }
}

4.CountDownLatch(倒计时门闩)

  • 用途:让一个或多个线程等待其他线程完成操作后继续执行。常用于初始化任务或批量处理。
  • 特点:基于AQS的共享模式,状态变量表示倒计数值(初始化为正数,递减到0时触发)。

代码示例

import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3); // 初始化计数器为3
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                System.out.println("子线程完成任务");
                latch.countDown(); // 计数器减1
            }).start();
        }
        latch.await(); // 主线程等待计数器归零
        System.out.println("所有任务完成,主线程继续");
    }
}

5.CyclicBarrier(循环屏障)

  • 用途:让一组线程相互等待,直到所有线程都到达某个屏障点后继续执行。支持重用,适用于多阶段任务。
  • 特点:虽然CyclicBarrier不是直接继承AQS,但内部使用ReentrantLock(基于AQS)实现同步。

代码示例

import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () -> 
            System.out.println("所有线程到达屏障,执行后续任务"));
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println("线程到达屏障");
                    barrier.await(); // 等待其他线程
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

总结

以上是Java中常见的基于AQS的实现类,它们覆盖了互斥锁、读写锁、资源控制、线程协调等多种并发场景。使用这些类时,注意线程安全和资源管理,避免死锁。AQS的设计模式(如状态变量和队列管理)确保了这些实现的高效性和可扩展性。在实际开发中,根据需求选择合适的同步器,并参考官方文档(如java.util.concurrent包)获取更多细节。

到此这篇关于Java 中 AQS 的几大经典实现的文章就介绍到这了,更多相关java aqs内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot自动注入的原理分析

    Spring Boot自动注入的原理分析

    这篇文章主要给大家分析介绍了关于Spring Boot自动注入的原理,文中通过示例代码介绍的非常详细,对大家的学习或者使用Spring Boot自具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-10-10
  • 使用spring stream发送消息代码实例

    使用spring stream发送消息代码实例

    这篇文章主要介绍了使用spring stream发送消息代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Spring无法解决循环依赖的五种场景分析

    Spring无法解决循环依赖的五种场景分析

    本文详细分析Spring框架中五类循环依赖问题(构造器注入、原型作用域、@Async、配置类、BeanPostProcessor),提出应急方案如@Lazy、重构设计,并强调通过单一职责、依赖倒置等设计原则避免循环依赖,需要的朋友可以参考下
    2025-05-05
  • SpringBoot拦截器的使用介绍

    SpringBoot拦截器的使用介绍

    大家好,本篇文章主要讲的是SpringBoot拦截器的使用介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • 浅谈Java实现面向对象编程java oop

    浅谈Java实现面向对象编程java oop

    这篇文章主要介绍了浅谈Java实现面向对象编程java oop,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • MybatisPlus修改时空字段无法修改的解决方案

    MybatisPlus修改时空字段无法修改的解决方案

    这篇文章主要介绍了MybatisPlus修改时空字段无法修改的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • java中List<String>转字符串形式常用方法总结(非常全!)

    java中List<String>转字符串形式常用方法总结(非常全!)

    这篇文章主要介绍了java中List<String>转字符串形式的相关资料,文中通过示例总结了五种字符串连接方法及进阶场景、性能优化与特殊字符处理技巧,需要的朋友可以参考下
    2025-05-05
  • Spring条件注解用法案例分析

    Spring条件注解用法案例分析

    这篇文章主要介绍了Spring条件注解用法,结合具体实例形式分析了Spring条件注解相关原理、使用方法及操作注意事项,需要的朋友可以参考下
    2019-11-11
  • 详解SpringBoot中自定义starter的开发与使用

    详解SpringBoot中自定义starter的开发与使用

    starter是SpringBoot中非常重要的一个机制,他是基于约定优于配置的思想所衍生出来的,本文主要介绍了SpringBoot中自定义starter的开发与使用,感兴趣的可以了解下
    2023-09-09
  • Java IO 之文件读写简单实例

    Java IO 之文件读写简单实例

    这篇文章主要介绍了Java IO 之文件读写简单实例的相关资料,需要的朋友可以参考下
    2017-06-06

最新评论