AQS 框架、JUC常见并发包 简述

AQS(AbstractQueuedSynchronizer)是 Java 中的一个强大的同步框架,为我们提供了实现各种同步器的基础。在本篇博客中,我们将介绍 AQS 框架的基本原理,并探讨几个常见的 AQS 实现:ReentrantLock、CountDownLatch 和 Semaphore。我们将了解它们的区别以及各自的优缺点。

1. AQS 框架简介

AQS 是 Java 并发包中的核心部分,它提供了一个基于 FIFO(first in first out 先进先出)排队的双向链表等待队列,用于管理等待线程并控制资源的获取和释放。AQS 提供了一些核心的方法供子类继承和实现。下面我们重点介绍几个常见的 AQS 实现。

2. AQS 框架适用场景

AQS 用于单个服务内部的线程同步和并发控制。适用于所有单体架构,或者微服务项目中单个服务内部的线程同步和并发控制。不适用于分布式部署项目,对于集群部署的微服务项目,需要额外考虑跨服务的分布式同步问题,并选择适合的分布式锁解决方案来实现分布式环境下的同步与控制。例如 ZooKeeper、Redisson 等提供的分布式锁实现

3. ReentrantLock(可重入锁)

ReentrantLock 是 AQS 框架的一个常见应用,它提供了独占模式的锁。多个线程可以重复获取和释放该锁,而不会因为重复获取而发生死锁。这个特性使得 ReentrantLock 可以用于更复杂的同步场景。

ReentrantLock内部使用了一个int变量来表示锁的持有状态,作为条件是占用资源,值为0时表示未锁定状态,大于0表示已锁定。

下面是一个简单的示例代码:

import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {private static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {lock.lock(); // 加锁,如果没有线程持有,则持有数加1返回。如果有线程持有,则持有数加1,并放到aqs等待队列排队try {// 执行保护的代码块} finally {lock.unlock(); // 释放锁,如果当前线程是此锁的持有者,则持有计数递减。如果保持计数现在为零,则释放锁。如果当前线程不是此锁的持有者,则抛出IllegalHonitorStateException}}
}

ReentrantLock 的优点是提供了可重入性,支持公平和非公平模式,并且具有更丰富的功能。缺点是相对于 synchronized 关键字有更高的复杂性和更多的开销。

4. CountDownLatch(倒计时门栓)

CountDownLatch 是一个同步机制,它允许一个或多个线程等待其他线程完成操作,它的构造器将会接收一个整数参数,表示需要等待的线程数量。

CountDownLatch内部也使用AQS的等待队列实现等待线程的阻塞,使用一个int类型的计数器来表示需要等待的线程数。

具体实现过程:

构造时将计数器初始化为传入的参数值。

countDown()方法会让计数器值减1,如果计数器变为0了,则唤醒等待队列中所有的线程

await()方法会首先将当前线程添加到AQS的等待队列中,然后判断计数器是否为0,如果不为0则一直等待。

import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {private static CountDownLatch latch = new CountDownLatch(3);public static void main(String[] args) throws InterruptedException {// 创建并启动多个线程for (int i = 0; i < 3; i++) {new Thread(() -> {// 执行操作latch.countDown(); // 操作完成后计数减1}).start();}latch.await(); // 等待计数为0// 所有操作完成后继续执行}
}

CountDownLatch 的优点是简单易用,可以很方便地实现等待其他线程完成的场景。缺点是一旦计数值确定后就无法修改,并且只能使用一次。

5. Semaphore(信号量)

Semaphore 是一种控制并发访问资源数量的同步工具。它允许多个线程同时访问共享资源,但需要限制总的访问线程数量。Semaphore 通过 AQS 的计数和等待机制来控制线程的获取和释放。

Semaphore内部也是通过一个int值表示许可数量来实现的;
acquire()方法会获取一个许可,如果没有就排队等待;
release()方法会释放一个许可。

下面是一个简单的示例代码:

import java.util.concurrent.Semaphore;
public class SemaphoreExample {private static Semaphore semaphore = new Semaphore(2);public static void main(String[] args) {// 创建并启动多个线程for (int i = 0; i < 5; i++) {new Thread(() -> {try {semaphore.acquire(); // 获取许可// 访问共享资源} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release(); // 释放许可}}).start();}}
}

Semaphore 的优点是可以控制资源的并发访问数量,可以用于限流等场景。缺点是相对于其他同步机制有更多的复杂性和开销。

总结

锁定对象:

  • ReentrantLock是一种互斥锁,用于保护共享资源免受并发访问的侵害。
  • CountDownLatch和Semaphore不是用来进行同步互斥的,CountDownLatch用来协调并行任务。
  • Semaphore用来控制对共享资源的访问数量。

实现原理:

  • ReentrantLock使用状态变量表示锁的可重入性。
  • CountDownLatch使用状态计数器,计数到0为0后释放所有等待线程。
  • Semaphore使用许可证计数来控制可以访问的线程数量。

使用场景:

  • ReentrantLock用于同步访问的临界区。
  • CountDownLatch用于等待一组异步任务完成。
  • Semaphore用于控制对某种资源的并发数量。

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

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

相关文章

kotlin中集合操作符

集合操作符 1.总数操作符 any —— 判断集合中 是否有满足条件 的元素&#xff1b; all —— 判断集合中的元素 是否都满足条件&#xff1b; none —— 判断集合中是否 都不满足条件&#xff0c;是则返回true&#xff1b; count —— 查询集合中 满足条件 的 元素个数&#x…

python科研绘图:条形图

条形图&#xff08;bar chart&#xff09;是一种以条形或柱状排列数据的图形表示形式&#xff0c;可以显示各项目之间的比较。它通常用于展示不同类别的数据&#xff0c;例如在分类问题中的不同类别、不同产品或不同年份的销售数据等。 条形图中的每个条形代表一个类别或一个数…

easyexcel根据模板导出Excel文件,表格自动填充问题

背景 同事在做easyexcel导出Excel&#xff0c;根据模板导出的时候&#xff0c;发现导出的表格&#xff0c;总会覆盖落款的内容。 这就很尴尬了&#xff0c;表格居然不能自动填充&#xff0c;直接怒喷工具&#xff0c;哈哈。 然后一起看了一下这个问题。 分析原因 我找了自…

MySQL - 系统库之 performance_schema

performance_schema &#xff1a;用于收集和存储关于数据库性能和资源利用情况的信息&#xff0c;可用于监控、分析和优化数据库的性能&#xff1a; 用途&#xff1a; 性能监控&#xff1a;performance_schema 用于监控数据库的性能。它提供了有关查询执行、锁等待、I/O操作、…

基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统

goframe-admin goframe-admin V1.0.0 平台简介 基于goframe2.5.4、vue3、tdesign-vue-next开发的全栈前后端分离的管理系统。前端采用tdesign-vue-next-starter 、vue3、pinia、tdesign-vue-next。 特征 高生产率&#xff1a;几分钟即可搭建一个后台管理系统认证机制&#x…

华为云资源搭建过程

网络搭建 EIP&#xff1a; 弹性EIP&#xff0c;支持IPv4和IPv6。 弹性公网IP&#xff08;Elastic IP&#xff09;提供独立的公网IP资源&#xff0c;包括公网IP地址与公网出口带宽服务。可以与弹性云服务器、裸金属服务器、虚拟IP、弹性负载均衡、NAT网关等资源灵活地绑定及解绑…

通过Google搜索广告传送的携带木马的PyCharm软件版本

导语 最近&#xff0c;一起新的恶意广告活动被发现&#xff0c;利用被入侵的网站通过Google搜索结果推广虚假版本的PyCharm软件。这个活动利用了动态搜索广告&#xff0c;将广告链接指向被黑客篡改的网页&#xff0c;用户点击链接后下载的并不是PyCharm软件&#xff0c;而是多种…

【代码数据】2023粤港澳大湾区金融数学建模B题分享

基于中国特色估值体系的股票模型分析和投资策略 首先非常建议大家仔细的阅读这个题的题目介绍&#xff0c;还有附赠的就是那个附件里的那几篇材料&#xff0c;我觉得你把这些内容读透理解了&#xff0c;就可以完成大部分内容。然后对于题目里它主要第一部分给出了常用的估值模…

AttributeError: partially initialized module ‘pandas‘ has no attribute ‘core‘

在使用jupyter notebook学习动手学深度学习时&#xff0c;出现以下错误&#xff1a; %matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, voca…

Linux命令(111)之groupadd

linux命令之groupadd 1.groupadd介绍 linux命令groupadd是用来创建新的用户组&#xff0c;用户组信息会被添加到系统文件(/etc/group)中。 2.groupadd用法 groupadd [参数] GroupName groupadd常用参数 参数说明-g指定用户组的gid号-r创建系统工作组-f如果组已经存在则成功…

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…

C#项目设计——学生成绩管理系统设计

学生成绩管理系统C语言.Net C#项目设计 全套代码加数据库文件&#xff0c;带设计报告&#xff0c;带设计报告哦&#xff01; 可以用Microsoft Visual Studio打开 用户名和密码在数据里。 报告部分内容&#xff1a; 设计一个学生成绩管理系统。包括“登录窗体”、“主窗体”和…

idea中启动多例项目配置

多实例启动 日常本地开发微服务项目时&#xff0c;博主想要验证一下网关的负载均衡以及感知服务上下线能力时&#xff0c;需要用到多实例启动。 那么什么是多实例启动嘞&#xff1f;简单说就是能在本地同时启动多个同一服务。打个比方项目中有一个 MobileApplication 服务&…

Android 13 - Media框架(13)- OpenMax(一)

这一节我们将了解Android OpenMax框架&#xff0c;该框架了解完成之后&#xff0c;我们会再回过头去了解 ACodec&#xff0c;将 MediaCodec - ACodec - OpenMax 连接起来&#xff0c;了解组件的创建控制以及 buffer 的流转。 本篇属于个人学习笔记&#xff0c;如有错误欢迎指出…

C# 使用.NET的SocketAsyncEventArgs实现高效能多并发TCPSocket通信

简介&#xff1a; SocketAsyncEventArgs是一个套接字操作得类&#xff0c;主要作用是实现socket消息的异步接收和发送&#xff0c;跟Socket的BeginSend和BeginReceive方法异步处理没有多大区别&#xff0c;它的优势在于完成端口的实现来处理大数据的并发情况。 BufferManager类…

服务熔断保护实践--Sentinal

目录 概述 环境说明 步骤 Sentinel服务端 Sentinel客户端 依赖 在客户端配置sentinel参数 测试 保护规则设置 设置资源名 设置默认的熔断规则 RestTemplate的流控规则 Feign的流控规则 概述 微服务有很多互相调用的服务&#xff0c;构成一系列的调用链路&#xf…

蜜罐系统HFish的部署与功能实测

1. 引入 根据参考1对蜜罐的定义&#xff1a; 蜜罐&#xff08;Honeypot&#xff09;是一个计算机科学领域的术语&#xff0c;指用于检测或防御未经授权的行为或黑客攻击的陷阱。其名称来源于其工作原理类似于用来诱捕昆虫的蜜罐。蜜罐通常伪装成看似有利用价值的网路、资料、…

3.15每日一题(分部积分求不定积分)

解法一&#xff1a;令lnx等于t&#xff1b;求出x与t的关系&#xff0c;带入f(lnx)的式子中&#xff1b;通过凑微分&#xff0c;分部积分等方法求出答案 注&#xff1a;在分部积分后&#xff0c;求不定积分时 &#xff08;1&#xff09;可以加项减项拆的方法求&#xff08;常规…

61. 旋转链表、Leetcode的Python实现

博客主页&#xff1a;&#x1f3c6;李歘歘的博客 &#x1f3c6; &#x1f33a;每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点&#xff0c;以及职场小菜鸡的生活。&#x1f33a; &#x1f497;点关注不迷路&#xff0c;总有一些&#x1f4d6;知识点&am…

小程序day02

目标 WXML模板语法 数据绑定 事件绑定 那麽問題來了&#xff0c;一次點擊會觸發兩個組件事件的話&#xff0c;該怎么阻止事件冒泡呢&#xff1f; 文本框和data的双向绑定 注意点: 只在标签里面用value“{{info}}”&#xff0c;只会是info到文本框的单向绑定&#xff0c;必须在…