并发控制利器Semaphore

2024-05-24 15:44
文章标签 并发 控制 利器 semaphore

本文主要是介绍并发控制利器Semaphore,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

并发控制利器:Semaphore详解与应用

简介

Semaphore 是Java并发编程中的一个重要工具,用于管理对共享资源的访问权限,确保系统资源不会因过度访问而耗尽。形象地说,Semaphore 可以比喻为交通信号灯,它控制着能够同时进入特定区域(如马路)的车辆数(线程数)。当一定数量的车辆(线程)进入后,其余车辆必须等待,直到有车辆离开,空出“车位”(许可证)为止。在编程中,Semaphore 通过协调线程访问,保证公共资源的合理分配。
在这里插入图片描述

应用场景

Semaphore 特别适用于有限资源访问控制的场景,例如数据库连接池管理、文件读写控制等。一个典型示例是数据库连接限制:假设你需要从数万个文件中读取数据,并将其保存至数据库,虽然读取操作(IO密集型)可以并行处理,但数据库连接数有限(例如10个)。此时,Semaphore 可以用来控制仅有10个线程能同时获取数据库连接,避免超出连接池容量。

public class SemaphoreTest {private static final int THREAD_COUNT = 30;private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);private static Semaphore s = new Semaphore(10);public static void main(String[] args) {for (int i = 0; i < THREAD_COUNT; i++) {threadPool.execute(new Runnable() {@Overridepublic void run() {try {s.acquire();System.out.println("Saving data...");s.release();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}});}threadPool.shutdown();}
}

在这个例子中,尽管启用了30个线程,但最多只有10个线程能够同时执行数据库保存操作,通过 Semaphore(10) 初始化,确保了并发访问的线程数不超过10。

其他方法及实现机制

Semaphore 提供了多个方法来帮助管理资源访问:

  • availablePermits():返回当前可用的许可证数量。
  • getQueueLength():返回等待获取许可证的线程数。
  • hasQueuedThreads():检查是否有线程正在等待许可证。
  • reducePermits(int reduction):减少指定数量的许可证,是一个受保护方法。
  • getQueuedThreads():返回所有等待的线程集合,同样是受保护方法。

Semaphore 的内部实现基于AQS(AbstractQueuedSynchronizer),利用了CLH队列来管理等待线程。CLH队列是一种FIFO(先进先出)的线程等待队列,当线程尝试获取许可证失败时,会被封装成节点加入到队列中等待。CLH队列的节点结构包含前驱节点和后继节点的引用,以及线程状态等信息,通过这些信息维护线程的等待顺序。

在尝试获取锁的操作中,AQS的acquire() 方法首先尝试快速获取资源,失败则通过addWaiter()方法将当前线程封装成节点并加入队列。此过程体现了CLH队列的结构和等待机制,确保了线程安全且高效地获取和释放资源。

总之,Semaphore 作为一种灵活的并发控制工具,通过限制并发访问的数量,有效管理共享资源,是解决资源竞争和提高系统并发能力的重要手段。

这篇关于并发控制利器Semaphore的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/998837

相关文章

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

Java JUC并发集合详解之线程安全容器完全攻略

《JavaJUC并发集合详解之线程安全容器完全攻略》Java通过java.util.concurrent(JUC)包提供了一整套线程安全的并发容器,它们不仅是简单的同步包装,更是基于精妙并发算法构建... 目录一、为什么需要JUC并发集合?二、核心并发集合分类与详解三、选型指南:如何选择合适的并发容器?在多

Java 结构化并发Structured Concurrency实践举例

《Java结构化并发StructuredConcurrency实践举例》Java21结构化并发通过作用域和任务句柄统一管理并发生命周期,解决线程泄漏与任务追踪问题,提升代码安全性和可观测性,其核心... 目录一、结构化并发的核心概念与设计目标二、结构化并发的核心组件(一)作用域(Scopes)(二)任务句柄

Redis高性能Key-Value存储与缓存利器常见解决方案

《Redis高性能Key-Value存储与缓存利器常见解决方案》Redis是高性能内存Key-Value存储系统,支持丰富数据类型与持久化方案(RDB/AOF),本文给大家介绍Redis高性能Key-... 目录Redis:高性能Key-Value存储与缓存利器什么是Redis?为什么选择Redis?Red

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

MySQL中处理数据的并发一致性的实现示例

《MySQL中处理数据的并发一致性的实现示例》在MySQL中处理数据的并发一致性是确保多个用户或应用程序同时访问和修改数据库时,不会导致数据冲突、数据丢失或数据不一致,MySQL通过事务和锁机制来管理... 目录一、事务(Transactions)1. 事务控制语句二、锁(Locks)1. 锁类型2. 锁粒

DNS查询的利器! linux的dig命令基本用法详解

《DNS查询的利器!linux的dig命令基本用法详解》dig命令可以查询各种类型DNS记录信息,下面我们将通过实际示例和dig命令常用参数来详细说明如何使用dig实用程序... dig(Domain Information Groper)是一款功能强大的 linux 命令行实用程序,通过查询名称服务器并输

深入解析Java NIO在高并发场景下的性能优化实践指南

《深入解析JavaNIO在高并发场景下的性能优化实践指南》随着互联网业务不断演进,对高并发、低延时网络服务的需求日益增长,本文将深入解析JavaNIO在高并发场景下的性能优化方法,希望对大家有所帮助... 目录简介一、技术背景与应用场景二、核心原理深入分析2.1 Selector多路复用2.2 Buffer