讲师中心 微信公众号
AI工具推荐 视频效率加速

Java中如何用Semaphore限制资源访问

胖芳君_2641

胖芳君_2641

发布时间:2025-06-19 23:18:02

|

842人浏览过

|

来源于php中文网

原创

semaphore的公平性会影响性能,1.公平模式下等待时间最长的线程优先获得许可,避免饥饿但增加开销;2.非公平模式允许插队,提高吞吐量但可能导致线程长时间等待;3.默认是非公平模式。处理异常时需捕获interruptedexception并重新中断,使用try-finally确保释放许可。semaphore与reentrantlock的区别在于,1.reentrantlock用于互斥访问和代码块保护,支持可重入和条件变量;2.semaphore控制多个资源的并发访问,适用于资源池等场景。选择依据是需求:需要互斥和高级功能用reentrantlock,控制多资源并发用semaphore。

Java中如何用Semaphore限制资源访问

在Java中,Semaphore用于控制对共享资源的并发访问数量。它本质上是一个计数器,可以用来限制同时访问特定资源的线程数量。当计数器大于零时,允许线程访问;当计数器为零时,线程必须等待。

Java中如何用Semaphore限制资源访问
import java.util.concurrent.Semaphore;

public class ResourcePool {

    private final Semaphore semaphore;
    private final Object[] resources;
    private final boolean[] used;

    public ResourcePool(int poolSize) {
        this.semaphore = new Semaphore(poolSize);
        this.resources = new Object[poolSize];
        this.used = new boolean[poolSize];

        for (int i = 0; i < poolSize; i++) {
            resources[i] = new Object(); // 假设资源是Object
            used[i] = false;
        }
    }

    public Object acquire() throws InterruptedException {
        semaphore.acquire(); // 请求一个许可,如果许可不可用,则阻塞
        return getResource();
    }

    public void release(Object resource) {
        if (returnResource(resource)) {
            semaphore.release(); // 释放一个许可
        }
    }

    private synchronized Object getResource() {
        for (int i = 0; i < resources.length; i++) {
            if (!used[i]) {
                used[i] = true;
                return resources[i];
            }
        }
        return null; // 不应该发生
    }

    private synchronized boolean returnResource(Object resource) {
        for (int i = 0; i < resources.length; i++) {
            if (resources[i] == resource) {
                if (used[i]) {
                    used[i] = false;
                    return true;
                } else {
                    // 资源已经被释放
                    return false;
                }
            }
        }
        return false; // 资源不在池中
    }

    public static void main(String[] args) throws InterruptedException {
        ResourcePool pool = new ResourcePool(3);

        for (int i = 0; i < 5; i++) {
            final int threadId = i;
            new Thread(() -> {
                try {
                    Object resource = pool.acquire();
                    System.out.println("Thread " + threadId + " acquired resource: " + resource);
                    Thread.sleep((long) (Math.random() * 1000)); // 模拟使用资源
                    pool.release(resource);
                    System.out.println("Thread " + threadId + " released resource: " + resource);

                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }).start();
        }

        Thread.sleep(5000); // 等待一段时间让线程完成
    }
}

Semaphore的公平性如何影响性能?

Semaphore可以配置为公平或非公平模式。公平模式下,等待时间最长的线程会优先获得许可。非公平模式下,线程可以“插队”,即如果当前有可用许可,即使有其他线程在等待,当前线程也可能获得许可。

Java中如何用Semaphore限制资源访问

公平性保证了所有线程都有机会访问资源,避免了饥饿现象。然而,公平性会带来额外的开销,因为需要维护等待队列的顺序。非公平模式通常具有更高的吞吐量,因为线程可以更快地获得许可,但可能会导致某些线程长时间等待。

立即学习“Java免费学习笔记(深入)”;

Java中如何用Semaphore限制资源访问

选择哪种模式取决于具体应用场景。如果对公平性有严格要求,则应选择公平模式。如果性能是关键,则可以选择非公平模式。默认情况下,Semaphore是非公平的。

Alibabacloud Sdk Client Initialization For Java
Alibabacloud Sdk Client Initialization For Java

在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。

下载

如何处理Semaphore使用中的异常情况?

在使用Semaphore时,需要处理InterruptedException异常,该异常可能在acquire()方法中抛出。这通常发生在线程在等待许可时被中断的情况下。处理InterruptedException的常见做法是捕获异常并执行一些清理工作,例如释放已经持有的资源,然后重新抛出中断异常,以便调用链上的其他代码可以处理中断事件。

此外,还需要注意Semaphore的释放操作。如果线程在没有持有许可的情况下调用release()方法,Semaphore的计数器可能会超出其初始值,这可能会导致并发问题。为了避免这种情况,应该始终确保线程在释放许可之前已经成功获取了许可。可以使用try-finally块来确保即使在发生异常的情况下,许可也能被正确释放。

Semaphore与ReentrantLock的区别是什么,何时使用哪个?

Semaphore和ReentrantLock都可以用于控制对共享资源的并发访问,但它们的设计目标和使用方式有所不同。

ReentrantLock提供了一种互斥锁机制,它只允许一个线程在任何给定时间访问临界区。ReentrantLock还提供了更多的功能,例如可重入性、公平性选择和条件变量。ReentrantLock通常用于保护代码块,确保在执行代码块期间只有一个线程可以访问共享资源。

Semaphore则是一种更通用的同步工具,它可以控制对多个资源的并发访问数量。Semaphore可以用于实现各种并发模式,例如有界队列、资源池和信号量。Semaphore通常用于控制对资源的访问,而不是保护代码块。

选择使用Semaphore还是ReentrantLock取决于具体的需求。如果需要互斥访问和更高级的锁定功能,则应选择ReentrantLock。如果需要控制对多个资源的并发访问数量,则应选择Semaphore。一般来说,如果只需要简单的互斥访问,synchronized关键字通常就足够了。

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

3578

2023.08.10

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

Buffalo框架路由与请求处理实操指南
Buffalo框架路由与请求处理实操指南

本专题讲解Buffalo框架路由与请求处理机制,涵盖路由注册与分组、资源路由、Handler编写规范、Context上下文方法、参数绑定、中间件编写挂载、Session与Cookie读写、Flash消息及错误页面定制方法。

60

2026.09.23

Buffalo框架零基础入门教程
Buffalo框架零基础入门教程

本专题整理Buffalo框架入门内容,涵盖Go环境准备、buffalo CLI安装、新项目生成、目录结构说明、dev热加载启动、数据库连接配置与常见报错排查,帮助新手按约定优于配置的思路跑通第一个Buffalo框架应用。

40

2026.09.23

Conan创建软件包配方指南
Conan创建软件包配方指南

本专题介绍通过conanfile.py创建软件包的方法,讲解包名、版本、依赖和构建设置等基础信息,以及source、build、package、package_info等常用方法的作用及编写思路。

40

2026.09.22

Conan二进制包配置指南
Conan二进制包配置指南

本专题介绍Conan根据操作系统、编译器、架构和构建类型生成二进制包的方法,讲解Profile、Settings、Options及Package ID的作用,帮助管理不同平台和编译环境下的包版本。

40

2026.09.22

Conan私有仓库搭建教程
Conan私有仓库搭建教程

本专题系统的讲解Conan私有仓库的搭建流程,涵盖仓库服务部署、存储目录配置、用户认证、权限划分和远程地址添加,并介绍内部C++依赖包的上传、下载及版本维护方法。

40

2026.09.22

loomy官网入口地址合集
loomy官网入口地址合集

本专题汇总了 Loomy 桌面 AI 助理的官方入口地址合集及使用指南。提供 macOS 与 Windows 客户端下载 。Loomy 是讯飞推出的桌面级 AI 工作搭子,支持文件整理、数据分析、网页操作及通过飞书/钉钉远程操控电脑,助你高效完成本地办公任务 。

40

2026.09.22

NumPy常见函数使用方法
NumPy常见函数使用方法

本专题整理 NumPy 常见函数使用方法相关教程,覆盖函数大全、参数用法、数组运算、统计聚合、排序处理、where 条件筛选、linspace 创建数列等常用场景,帮助读者快速掌握 NumPy 函数调用思路和实际数据处理技巧。

60

2026.09.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn