并发控制利器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

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次

键盘快捷键:提高工作效率与电脑操作的利器

键盘快捷键:提高工作效率与电脑操作的利器 在数字化时代,键盘快捷键成为了提高工作效率和优化电脑操作的重要工具。无论是日常办公、图像编辑、编程开发,还是游戏娱乐,掌握键盘快捷键都能带来极大的便利。本文将详细介绍键盘快捷键的概念、重要性、以及在不同应用场景中的具体应用。 什么是键盘快捷键? 键盘快捷键,也称为热键或快捷键,是指通过按下键盘上的一组键来完成特定命令或操作的方式。这些快捷键通常涉及同

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

java线程深度解析(五)——并发模型(生产者-消费者)

http://blog.csdn.net/Daybreak1209/article/details/51378055 三、生产者-消费者模式     在经典的多线程模式中,生产者-消费者为多线程间协作提供了良好的解决方案。基本原理是两类线程,即若干个生产者和若干个消费者,生产者负责提交用户请求任务(到内存缓冲区),消费者线程负责处理任务(从内存缓冲区中取任务进行处理),两类线程之

java线程深度解析(四)——并发模型(Master-Worker)

http://blog.csdn.net/daybreak1209/article/details/51372929 二、Master-worker ——分而治之      Master-worker常用的并行模式之一,核心思想是由两个进程协作工作,master负责接收和分配任务,worker负责处理任务,并把处理结果返回给Master进程,由Master进行汇总,返回给客

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

使用协程实现高并发的I/O处理

文章目录 1. 协程简介1.1 什么是协程?1.2 协程的特点1.3 Python 中的协程 2. 协程的基本概念2.1 事件循环2.2 协程函数2.3 Future 对象 3. 使用协程实现高并发的 I/O 处理3.1 网络请求3.2 文件读写 4. 实际应用场景4.1 网络爬虫4.2 文件处理 5. 性能分析5.1 上下文切换开销5.2 I/O 等待时间 6. 最佳实践6.1 使用 as