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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于Java中静态代码块的执行浅析

    关于Java中静态代码块的执行浅析

    这篇文章主要给大家介绍了关于Java中静态代码块执行的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-09-09
  • Java HashMap算法原理详细讲解

    Java HashMap算法原理详细讲解

    在java开发中,HashMap是最常用、最常见的集合容器类之一,文中通过示例代码介绍HashMap为啥要二次Hash,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-02-02
  • 使用Java和ffmpeg把音频和视频合成视频的操作方法

    使用Java和ffmpeg把音频和视频合成视频的操作方法

    这篇文章主要介绍了使用Java和ffmpeg把音频和视频合成视频,本文通过实例代码给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • java远程连接调用Rabbitmq的实例代码

    java远程连接调用Rabbitmq的实例代码

    本篇文章主要介绍了java远程连接调用Rabbitmq的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • SpringCloud如何搭建一个多模块项目

    SpringCloud如何搭建一个多模块项目

    这篇文章主要介绍了SpringCloud如何搭建一个多模块项目,记录下使用SpringCloud创建多模块项目,一步一步记录搭建的过程,感兴趣的可以了解一下
    2021-05-05
  • Java中的关键字之final详解

    Java中的关键字之final详解

    这篇文章主要介绍了Java中的关键字之final详解,final关键字算是个高频的java基础问题了,面试官可能会问说说final,final修饰的抽象类能够被继承吗等等,下面汇总关于final关键字的知识点,需要的朋友可以参考下
    2024-01-01
  • Java 合并多个MP4视频文件

    Java 合并多个MP4视频文件

    这篇文章主要介绍了Java 合并多个MP4视频文件的方法,帮助大家利用Java处理视频,提高办公效率,感兴趣的朋友可以了解下
    2020-11-11
  • Java实现折半插入排序算法的示例代码

    Java实现折半插入排序算法的示例代码

    折半插入排序(Binary Insertion Sort)是对插入排序算法的一种改进。不断的依次将元素插入前面已排好序的序列中。本文将利用Java语言实现这一排序算法,需要的可以参考一下
    2022-08-08
  • java HashMap 的工作原理详解

    java HashMap 的工作原理详解

    本文主要介绍java HashMap 的资料,这里整理了相关资料,并详细说明了HashMap的用法,有需要的小伙伴可以参考下
    2016-09-09
  • SpringCloud使用Nacos作为配置中心统一管理配置方式

    SpringCloud使用Nacos作为配置中心统一管理配置方式

    文章介绍了如何引入依赖、创建bootstrap.properties文件、添加配置信息、使用注解动态获取及刷新配置等步骤,以便优先从Nacos中获取配置信息
    2026-05-05

最新评论