【并发知识点】AQS的实现原理及应用

news2024/9/22 21:15:50

系列文章目录

AQS的实现原理及应用
CAS的实现原理及应用

在这里插入图片描述


文章目录

  • 系列文章目录
  • 前言
  • 一、AQS是什么?
    • 1、应用场景
    • 2、优缺点
  • 二、案例应用
    • 1.使用AQS来实现一个简单的互斥锁
    • 2.模拟赛龙舟程序
  • 总结


前言

在Java技术方面,AQS指的是AbstractQueuedSynchronizer(抽象队列同步器)。它是Java并发包中的一个重要组件,可以提供一种基于锁和信号量的同步机制,用于控制多线程之间的访问和共享资源。


一、AQS是什么?

AQS的核心思想是将多线程的进入和退出操作都放入一个FIFO(先进先出)的等待队列中,通过对这个等待队列的管理来控制线程的并发访问和同步。具体来说,AQS通过内部的state状态变量来表示锁或信号量的状态,当state为0时表示没有被占用,当state为1时表示被占用。此外,AQS还提供了一个Condition对象,用于在等待队列中挂起和唤醒线程。

在应用中,开发人员可以通过继承AQS并实现其内部的acquire和release方法来实现自己的同步机制。acquire方法用于获取锁或信号量,当state为0时会将线程加入等待队列中,直到state状态变为1才会获得锁或信号量。release方法则用于释放锁或信号量,并通知等待队列中的线程可以继续执行。

总的来说,AQS是Java并发包中非常重要的一个组件,它为多线程之间的协作提供了一种简单而高效的机制。当然,开发人员需要深入理解AQS的内部实现,才能更好地使用它来实现自己的同步机制。

1、应用场景

AQS的应用场景非常广泛。它可以用于实现各种同步机制,如互斥锁、读写锁、信号量、倒计时器等等。其中最常见的应用就是锁的实现,如ReentrantLock、ReentrantReadWriteLock、StampedLock等。这些锁都是基于AQS实现的,不同的锁通过实现不同的tryAcquire和tryRelease方法来实现不同的同步策略。此外,AQS还可以用于实现自定义同步机制,如实现一个有界队列、一个线程池等等。

2、优缺点

我们来分析一下AQS的优缺点。AQS的主要优点是灵活性、可扩展性和高并发性。它可以非常方便地实现各种同步机制,并且能够自适应地根据不同的应用场景进行优化。但是,AQS的实现比较复杂,需要对锁的实现细节有一定的了解,同时也需要避免出现死锁和饥饿等问题。因此,在使用AQS时需要谨慎操作。

二、案例应用

1.使用AQS来实现一个简单的互斥锁

代码如下(示例):

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class Mutex {
    private static class Sync extends AbstractQueuedSynchronizer {
        // 当state为0时,表示锁没有被占用;当为1时,表示锁已被占用
        protected boolean isHeldExclusively() {
            return getState() == 1;
        }

        // 尝试获取锁,如果state为0,则获取成功;否则加入等待队列
        public boolean tryAcquire(int acquires) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        // 释放锁
        protected boolean tryRelease(int releases) {
            if (getState() == 0) throw new IllegalMonitorStateException();
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }
    }

    // 创建一个Sync对象作为锁
    private final Sync sync = new Sync();

    // 获取锁
    public void lock() {
        sync.acquire(1);
    }

    // 释放锁
    public void unlock() {
        sync.release(1);
    }
}

在上面的代码中,我们定义了一个内部类Sync,它继承了AbstractQueuedSynchronizer并重写了其内部的tryAcquire和tryRelease方法。在tryAcquire方法中,我们使用compareAndSetState方法来尝试获取锁,如果state为0,则获取成功,并将当前线程设置为锁拥有者;否则加入等待队列。在tryRelease方法中,我们简单地将state设置为0,并将锁拥有者设置为null。

在Mutex类中,我们将Sync对象作为锁,并实现了lock和unlock方法来获取和释放锁。这样,我们就可以使用Mutex来实现互斥锁的功能了。

2.模拟赛龙舟程序

在这个程序中,我们将使用AQS来实现一个裁判的计时器,模拟一个赛龙舟比赛中多支队伍竞争的场景。每个队伍都会在启动时创建一个独立的线程,并在程序中使用Semaphore来模拟龙舟的运动。同时,程序中还会使用CountDownLatch来控制所有龙舟同时开始比赛,并使用CyclicBarrier来模拟所有队伍完成比赛后的庆祝活动。
代码如下(示例):

import java.util.concurrent.*;

public class DragonBoatRace {
    private static final int TEAM_NUM = 4; // 参赛队伍数
    private static final int BOAT_NUM = 1; // 龙舟数量
    private static final Semaphore semaphore = new Semaphore(BOAT_NUM);
    private static final CountDownLatch startLatch = new CountDownLatch(TEAM_NUM);
    private static final CyclicBarrier finishBarrier = new CyclicBarrier(TEAM_NUM);

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(TEAM_NUM);
        for (int i = 0; i < TEAM_NUM; i++) {
            executorService.submit(new Team(i + 1));
        }
        startLatch.await(); // 等待所有队伍准备就绪
        System.out.println("比赛开始!");
        semaphore.acquire(); // 获取龙舟信号量
        System.out.println("龙舟已经准备好!");
        Thread.sleep(2000); // 等待2秒,模拟龙舟前进
        semaphore.release(); // 释放龙舟信号量
        System.out.println("比赛结束!");
        finishBarrier.await(); // 等待所有队伍完成比赛
        System.out.println("所有队伍完成比赛,开始庆祝!");
        executorService.shutdown(); // 关闭线程池
    }

    static class Team implements Runnable {
        private final int teamId;

        public Team(int teamId) {
            this.teamId = teamId;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000 * teamId); // 模拟队伍准备时间
                System.out.println("队伍" + teamId + "已准备就绪!");
                startLatch.countDown(); // 准备就绪,计数器减一
                semaphore.acquire(); // 获取龙舟信号量
                System.out.println("队伍" + teamId + "已上船,准备出发!");
                Thread.sleep(2000); // 等待2秒,模拟龙舟前进
                System.out.println("队伍" + teamId + "已完成比赛!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release(); // 释放龙舟信号量
                try {
                    finishBarrier.await(); // 等待其他队伍完成比赛
                    System.out.println("队伍" + teamId + "正在庆祝!");
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

在这个程序中,我们模拟了4个队伍参加赛龙舟比赛。每个队伍都在启动时创建一个独立的线程,并在比赛前等待1~4秒的准备时间。当所有队伍都准备就绪后,裁判发出比赛开始信号,龙舟开始前进。程序中使用Semaphore来控制龙舟数量,每次只有一个队伍可以使用龙舟。当某个队伍完成比赛后,程序会使用CyclicBarrier来等待其他队伍完成比赛,并且进行庆祝活动。

总之,基于AQS的Java多线程程序可以很好地模拟赛龙舟比赛中的多支队伍竞争的场景。通过使用Semaphore、CountDownLatch和CyclicBarrier等多种同步机制,我们可以实现复杂的线程协作和同步操作。


总结

以上就是今天要讲的内容,本文仅仅简单介绍了AQS在Java中的简单应用。

最后祝大家端午快乐,附包粽子图一张
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/673473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023最新高薪岗位大爆料,大模型算法工程师!凭什么人均月薪50K

大模型算法工程师工资收入一般多少钱一个月&#xff1f; 最多人拿50K以上占 53.7%&#xff0c;2023年较2022年增长了10%。 按学历统计&#xff0c;本科工资&#xffe5;41.9K。 按经验&#xff0c;1-3年工资&#xffe5;40.0K。 一起来看华为招聘的大模型工程师的工资水准 岗位…

[补充]机器学习实战|第二周|第2章:监督学习|课后习题

目录 第二章 监督学习 2. 使用不同的超参数&#xff0c;如kernel"linear"和kernel“rbf”&#xff0c;尝试一个支持向量机回归器。并思考最好的SVR预测器是如何工作的&#xff1f; [代码]3. 为MNIST数据集构建一个分类器&#xff0c;并在测试集上达成超过97%的精度…

关于Java中单例模式(饿汉模式和懒汉模式)的简析

目录 一.什么是单例模式 二.饿汉模式和懒汉模式 饿汉模式 代码 懒汉模式 代码 关于多线程安全的问题 如何解决懒汉模式多线程安全问题 双if判断 一.什么是单例模式 简单来说,就是我们在程序中通过代码进行限制,在该程序中 只能创建一个对象 二.饿汉模式和懒汉模式 …

【2023,学点儿新Java-17】变量与运算符:Java中的关键字及类型划分(附: 官网) | 保留字 | 字面量 | 附:Java部分关键字介绍

前情回顾&#xff1a; 【2023&#xff0c;学点儿新Java-16】编程语言的学习方法总结 | 编程的本质和架构 | 如何深度理解编程知识和技能 | 如何成为优秀的软件开发工程师 | 附&#xff1a;Java初学者的困惑&#xff01;【2023&#xff0c;学点儿新Java-15】案例分享&#xff1…

机器视觉初步7:模板匹配专题

今天端午&#xff0c;祝各位端午安康&#xff01; 今天来说说模板匹配这个专题。 模板匹配&#xff08;Template Matching&#xff09;是一种图像处理技术&#xff0c;用于在一幅图像上查找与另一幅模板图像相同的区域。模板图像和待匹配图像的大小相同。模板匹配的目的是在待…

【MongoDB大作业】MongoDB服务器的部署

【MongoDB大作业】MongoDB服务器的部署 作业要求作业步骤一、在VMware Workstations安装Linux操作系统&#xff08;最小安装即可&#xff09;二、安装完成后登录系统三、将ip地址设置为固定ip地址192.168.80.134四、设置虚拟网络编辑器五、使用 CRT 工具远程连接虚拟机六、下载…

《项目实战》构建SpringCloud alibaba项目(一、构建父工程、公共库、网关))

系列文章目录 构建SpringCloud alibaba项目&#xff08;一、构建父工程、公共库、网关&#xff09; 构建SpringCloud alibaba项目&#xff08;二、构建微服务鉴权子工程store-authority-service&#xff09; 文章目录 系列文章目录1、概要2、整体架构流程2.1、技术结构组成部分…

非监督学习

聚类Clustering 查看大量数据点&#xff0c;自动找到彼此相关或相似的数据点 K-means算法 原理 1.随机选择点&#xff0c;找聚类的中心位置。将点分配给簇质心 2.移动簇质心 不断重复这两个步骤 优化目标 成本函数失真函数distortion 在每次迭代中&#xff0c;失真成本…

极致呈现系列之:Echarts旭日图的绚丽奇观

目录 什么是旭日图旭日图的特性及应用场景旭日图的特性应用场景 旭日图常用的配置项创建基本的旭日图自定义旭日图样式样式旭日图的高级应用 什么是旭日图 旭日图是一种可视化图表&#xff0c;用于展示层级结构和层级之间的关系。它以一个圆形为基础&#xff0c;由多层的环形图…

【从零开始学习JAVA | 第七篇】API 简介

目录 前言 API介绍&#xff1a; 总结&#xff1a; 前言 这篇章为前导性文章&#xff0c;主要向大家介绍了什么是API&#xff0c;不要求掌握&#xff0c;感兴趣的小伙伴们可以看一看。 API介绍&#xff1a; API&#xff08;Application Programming Interface&#xff09;是指…

webpack原理之开发第一个loader

一. 搭建项目结构 整体项目结构如图&#xff1a; 1. 初始化包管理器package.json npm init -y 2. 打包入口文件src/main.js 3. 单页面入口public/index.html 4. 配置webpack.config.js const path require(path) const HtmlWebpackPlugin require("html-webpack-plu…

ChatBot聊天机器人学习1

1、Bot定义 能执行大量自动化、高速或机械式、繁琐的工作的计算机程序&#xff0c;包括但不仅限于聊天功能 2、Retrieval-based KE&#xff08;知识网络&#xff09;基于信息的提取。&#xff08;检索的过程中有延迟&#xff0c;设置比较快捷的检索方式&#xff09; 2.1 Int…

一看就懂的gulp操作指南:让前端工作变得更加轻松

文章目录 I. 简介什么是gulp为什么要使用gulp安装gulp II. Gulp入门任务&#xff08;task&#xff09;和流&#xff08;stream&#xff09;的概念使用gulp来处理文件基本的gulp任务&#xff08;拷贝文件、压缩文件、编译Sass等&#xff09; III. Gulp进阶使用插件开发面向生产的…

基于Python+tensorflow深度学习VGG-19图像风格迁移+自动去噪(MNIST数据集)机器学习+人工智能+神经网络——含全部Python工程源码

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境TensorFlow 环境 模块实现1. 图片处理2. 模型构造 系统测试工程源代码下载其它资料下载 前言 本项目基于 MNIST 数据集&#xff0c;使用 VGG-19 网络模型&#xff0c;将图像进行风格迁移&#xff0c;实现去噪功…

数字信号处理课程设计——调制与解调

文字目录 数字信号处理课程设计 摘要&#xff1a; 1绪论 1.1通信信号的调制与解调 1.2设计题目 2卷积定理和希尔伯特公式理论推导 2.1卷积定理 ​2.2希尔伯特公式 3信号DSB调制与希尔伯特解调 3.1过程框图 3.2相关理论推导 3.2.1卷积定理在调制中的应用 3.2.2希尔…

某马 qiankun 公开课 学习记录

端午早晨阳光正好&#xff0c;起来学习一小下 客观评价一哈&#xff1a;此视频适合不了解 qiankun 的朋友入门观看&#xff0c;更详细的使用方法还是推荐 qiankun 官网哦&#xff0c;老师讲的生动活泼&#xff0c;值得萌新一听 某马 qiankun 公开课 - bilibili ovo很多公司的…

高通Camera Log Debug 知识点

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、Camx UMD Log Debug二、Camx KMD log Debug三、常用缩写解释四、参考文献 一、Camx UMD Log Debug 1.1 两种方式设置camx UMD Log /vendor/etc/cam…

GPT-3.5眼中的编程语言之最:Python的卓越之处

当谈论编程语言的选择时&#xff0c;每个开发者都有自己的偏好和理由。作为GPT-3.5&#xff0c;以我的分析和学习能力&#xff0c;我也有自己心目中的编程语言之最。在众多编程语言中&#xff0c;Python在我的眼中独树一帜&#xff0c;是最令人着迷和受欢迎的编程语言之一。 首…

面试经典150题(1)

文章目录 前言除自身以外数组的乘积要求思路代码 跳跃游戏|要求题解代码 跳跃游戏||要求题解代码 前言 今天开始我将陆续为大家更新面试经典150题中较难理解的题目。今天我为大家分享的是&#xff0c;除自身以外数组的乘积、跳跃游戏| 和 跳跃游戏||。 除自身以外数组的乘积 …

【unity之UiI专题】GUI(IMGUI)详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…