当前位置: 首页 > news >正文

并发控制之Semaphore

Semaphore

作用

信号量,用于控制同时访问特定资源的线程数量,通过协调各个线程,以确保对共享资源的访问不会导致冲突或数据不一致等问题,有点类似令牌桶,内部维护一组许可证,

acquire获取许可证,获取到了就执行,没获取到就阻塞直到有许可证

release 释放许可证

示例代码

import java.util.concurrent.Semaphore;public class Test {public static void main(String[] args) {final Semaphore semaphore = new Semaphore(4);for (int i = 0; i < 5; i++) {new Thread(() -> {try {semaphore.acquire();// 获取许可证,没获取到就阻塞在这里System.out.println(Thread.currentThread().getName() + " 获得许可证,开始执行任务");Thread.sleep((long) (Math.random() * 1000));System.out.println(Thread.currentThread().getName() + " 执行任务完毕,释放许可证");semaphore.release();// 执行完毕释放许可证} catch (InterruptedException e) {e.printStackTrace();}}).start();}}
}

实现原理

static final class NonfairSync extends Sync {private static final long serialVersionUID = -2694183684443567898L;NonfairSync(int permits) {super(permits);}protected int tryAcquireShared(int acquires) {return nonfairTryAcquireShared(acquires);}}/*** Fair version*/static final class FairSync extends Sync {private static final long serialVersionUID = 2014338818796000944L;FairSync(int permits) {super(permits);}protected int tryAcquireShared(int acquires) {for (;;) {if (hasQueuedPredecessors())return -1;int available = getState();int remaining = available - acquires;if (remaining < 0 ||compareAndSetState(available, remaining))return remaining;}}}

内部通过继承AbstractQueuedSynchronizer来实现其功能,有公平锁和非公平锁的实现,调用acquire方法,判断当前许可证数量大于0,就是用CAS操作许可证数量减1,线程就可以执行

许可证数量等于0 ,就把线程加入到AQS的等待队列中等待唤醒获取许可证再执行

http://www.lryc.cn/news/506469.html

相关文章:

  • 第R3周:RNN-心脏病预测
  • 【数值特性库】入口文件
  • RestTemplate实时接收Chunked编码传输的HTTP Response
  • GIT区域介绍及码云+GIt配置仓库
  • 网络安全怎么学习
  • PugiXML,一个高效且简单的 C++ XML 解析库!
  • Linux设备树的驱动开发
  • 连锁?下沉?AI?2025年餐饮新活力!
  • Javascript中如何实现函数缓存?函数缓存有哪些应用场景?
  • 子页面访问父页面
  • 芯片级IO (Pad) Ring IP Checklist
  • 计算机毕业设计论文指导
  • Electron-Vue 开发下 dev/prod/webpack server各种路径设置汇总
  • Vue.js前端框架教程9:Vue插槽slot用法
  • 初学stm32 --- NVIC中断
  • Jest 入门指南:从零开始编写 JavaScript 单元测试
  • 【Java Web】Axios实现前后端数据异步交互
  • React 第十七节 useMemo用法详解
  • 鸿蒙项目云捐助第十五讲云数据库的初步使用
  • 如何构建一个可信的联邦RAG系统。
  • 【深度学习之三】FPN与PAN网络详解
  • Qt学习笔记第71到80讲
  • 以管理员身份运行
  • 用 Python 实现井字棋游戏
  • 06 实现自定义AXI DMA驱动
  • SpringBoot集成ENC对配置文件进行加密
  • 初学stm32 ——— 串口通信
  • qwt 多Y轴 项目效果
  • Java中通过ArrayList扩展数组
  • Java:链接redis报错:NoSuchElementException: Unable to validate object