AQS的7个同步组件详解及示例代码

104 篇文章 ¥99.90 ¥299.90
本文详细介绍了Java的AQS(AbstractQueuedSynchronizer)框架下的7个同步组件:CountDownLatch、CyclicBarrier、Semaphore、ReentrantLock、ReentrantReadWriteLock、Phaser和SynchronousQueue,并提供了相应的示例代码,帮助开发者理解和应用这些同步工具,以实现多线程环境中的安全和有序执行。

AQS(AbstractQueuedSynchronizer)是Java中用于构建同步器的基础框架。它提供了一组同步组件,可以帮助开发者实现各种复杂的同步机制。本文将详细介绍AQS的7个同步组件,并提供相应的示例代码。

  1. CountDownLatch(倒计时门闩)
    CountDownLatch是一种同步工具,允许一个或多个线程等待其他线程完成操作后再继续执行。它通过一个计数器实现,初始值为线程数,每个线程完成操作时计数器减一,当计数器为0时,等待的线程将被释放。

示例代码:

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample
### Java AQS 工作原理及使用详解 #### 一、AQS 的基本概念 AbstractQueuedSynchronizer (简称 AQS),是一个用于构建锁和其他同步器的基础框架。它通过一个 `int` 类型的状态值 (`state`) 来表示资源的共享情况,并提供了一种 FIFO 队列来管理线程之间的竞争。 - **核心字段**: AQS 使用了一个名为 `state` 的整数变量来记录同步状态,该变量可以通过原子方式更新以确保线程安全[^2]。 - **队列模型**: 当多个线程争夺同一个资源时,未能获得资源的线程会被加入到 CLH(Craig, Landin, and Hagersten locks)队列中等待。这种队列是一种双向链表结构,可以有效减少上下文切换带来的开销[^3]。 --- #### 二、AQS 的工作流程 1. **获取锁的过程**: - 调用者尝试获取锁时,如果当前 `state` 值允许,则直接获取并修改 `state`;否则进入同步队列排队。 - 如果线程无法立即获取锁,将会被封装成一个节点(Node),并挂载到 CLH 队列中等待唤醒[^4]。 2. **释放锁的过程**: - 当持有锁的线程完成任务后,会调用 `release()` 方法释放锁。 - 此时,AQS 将重新计算 `state` 并通知下一个等待中的线程去尝试获取锁。 3. **条件变量支持**: - AQS 提供了对条件变量的支持,这使得开发者可以在某些特定条件下让线程暂停运行直到满足条件后再继续执行。 - 这部分功能主要由 `ConditionObject` 实现,其中涉及两个独立的队列:一个是主线程的竞争队列,另一个是条件队列[^4]。 --- #### 三、AQS 的两种模式 AQS 支持两种不同的资源共享模式: 1. **独占模式**: - 只能有一个线程占用资源,在大多数情况下对应的是互斥锁的行为。 - JDK 中典型的例子有 ReentrantLock 和 Semaphore(permit=1)。 2. **共享模式**: - 多个线程可以同时访问资源,适用于读写锁场景下允许多个只读操作的情况。 - 如 CountDownLatch 或 CyclicBarrier 所使用的机制就是基于此模式实现的。 --- #### 四、AQS 的典型应用案例 以下是几个常见的基于 AQS 构建的工具类及其用途说明: 1. **ReentrantLock** - 是一种可重入的互斥锁,提供了与 synchronized 关键字类似的锁定行为,同时还增加了更多高级特性,比如公平锁选项以及中断响应能力等。 2. **CountDownLatch** - 允许一个或多个线程一直等到其他一些线程完成一系列操作之后再继续执行。 - 它的核心逻辑在于维护计数值,并随着每次 countDown() 减少直至零触发后续动作。 3. **CyclicBarrier** - 让一组线程互相协作到达某个屏障点之前都不能向前推进,非常适合用来解决分阶段处理的任务需求。 4. **Semaphore** - 控制同一时刻最多有多少个线程能够访问某项有限资源集合。 5. **ReadWriteLock** - 区分为读锁和写锁两部分,从而提高并发度——即允许多个读者或者单一作者存在但不允许两者混合发生冲突。 --- #### 五、代码示例 下面给出一段简单的自定义锁实现作为演示如何利用 AQS 创建新的同步组件实例: ```java public class MyMutex extends AbstractQueuedSynchronizer { @Override protected boolean tryAcquire(int acquires) { if (compareAndSetState(0, 1)) { // CAS 操作设置 state setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } @Override protected boolean tryRelease(int releases) { if (getState() == 0) throw new IllegalMonitorStateException(); setExclusiveOwnerThread(null); setState(0); // 清空状态 return true; } public void lock() { acquire(1); } public void unlock() { release(1); } } ``` 上述代码片段展示了怎样借助 AQS 快速搭建起一套基础版的手动控制权限分配方案。 --- ### 总结 通过对 AQS 的学习可以看出其设计精妙之处不仅限于简单地实现了各种类型的锁机构,更重要的是为开发人员提供了一个高度灵活且易于扩展的抽象层面上的操作接口集锦。无论是初学者还是资深工程师都能从中受益匪浅!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code_welike

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值