信号量Semaphore的使用

简介: 允许多个线程同时访问:信号量(Semaphore)信号量为多线程协作提供了更为强大的控制方法。广义上说,信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问一个资源,而信号量指定多个线程访问同一个资源。

允许多个线程同时访问:信号量(Semaphore)

信号量为多线程协作提供了更为强大的控制方法。广义上说,信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问一个资源,而信号量指定多个线程访问同一个资源。
信号主要提供以下的构造函数。

public Semaphore(int permits);//permits 指定信号量的准入数
public Semaphore(int permits,boolean fair);//第二个参数指定是否公平

在构造信号量时,必须指定信号量的准入数,即同时能申请多少许可,若一个线程每次只申请一个许可,这就相当于指定了同时允许多少个线程能访问同一资源。
信号量的主要逻辑方法包括以下几种:

public void acquire();
public void acquireUninterruptibly();
public boolean tryAcquire();
public boolean tryAcquire(long timeout,TimeUnit unit);
public void release();

acquire()方法尝试获得一个准入的许可。若无法获得,线程会等待,直到有线程释放一个许可或者线程被中断。acquireUninterruptibly()方法和acquire()方法类似,但是不能相应中断。tryacquire()尝试获得一个许可,成功返回true失败返回false,他不会进行等待,立即返回。release()用于在线程访问资源结束后,释放一个许可,使其他线程可以进行资源访问。
下面我们使用一个例子来演示信号量的使用:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemapDemo implements Runnable {

    final Semaphore semp=new Semaphore(5);

    @Override
    public void run() {
        // TODO Auto-generated method stub
        try {
            semp.acquire();
            Thread.sleep(2000);
            System.out.println(Thread.currentThread().getId()+":done!");
            semp.release();
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ExecutorService exec=Executors.newFixedThreadPool(20);
        final SemapDemo demo=new SemapDemo();
        for(int i=0;i<20;i++) {
            exec.submit(demo);
        }
    }

}

可以看到程序会限制执行这段代码的线程数,观察结果可以看到每次5个线程一组,因为我们设置了允许5个许可的信号量。

相关文章
|
11月前
|
开发框架 人工智能 安全
鸿蒙HarmonyOS应用开发 | 「鸿蒙技术分享」HarmonyOS NEXT元服务卡片实战体验
HarmonyOS NEXT的发布对华为及整个行业都产生了深远的影响。它不仅展示了华为的技术实力,还敏锐地把握了市场需求。同时,吸引了更多的开发者和合作伙伴加入鸿蒙生态体系,共同推动鸿蒙生态的繁荣发展。
727 20
鸿蒙HarmonyOS应用开发 | 「鸿蒙技术分享」HarmonyOS NEXT元服务卡片实战体验
|
7月前
|
人工智能 自然语言处理 Java
从国外到国产,AI 编程工具混战,开发者究竟该如何抉择?
AI编程工具正深刻变革开发模式,从国外的GitHub Copilot、Cursor、Trae到国内的飞算JavaAI与通义灵码,各具特色。Copilot依托开源代码与强大模型提升效率,但成本高且偶有“AI幻觉”;Cursor适合中高级开发者,续写速度快但团队版有限制;Trae以免费GPT-4和中文界面吸引用户,但可持续性存疑。国产工具方面,飞算JavaAI专注全流程Java开发,一键生成工程代码,大幅提升效率;通义灵码支持多语言,功能丰富且与IDE无缝集成。开发者需根据语言、阶段、成本等因素权衡选择,找到最适合自身需求的工具,实现开发效率与质量的飞跃。
|
11月前
|
供应链 数据可视化 搜索推荐
旅游产品策划,哪款办公软件能激发无限创意?
在竞争激烈的旅游行业中,高效的团队协作和个人学习效率至关重要。本文深入剖析了六款可视化团队协作软件,包括板栗看板、Trello、Airtable、Asana、Monday.com 和 Notion,旨在为旅游公司提供全面的软件选择参考。这些软件不仅能够清晰呈现复杂的业务流程,促进信息高效流通,还具备强大的数据统计和团队协作功能,尤其适合 MBTI 类型中倾向于有序规划的 J 型人格。
197 9
|
存储 Prometheus 监控
服务器监控软件Prometheus
【10月更文挑战第19天】
225 6
|
Kubernetes 网络协议 容器
在K8S中,Pod的健康检查方式有哪些?
在K8S中,Pod的健康检查方式有哪些?
|
存储 算法 搜索推荐
掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】
掌握区间合并:解决实际问题的算法策略和应用案例【python LeetCode题目56】
|
存储 JavaScript API
vuex和pinia区别
vuex和pinia区别
263 0
|
Java Maven 开发工具
【IntelliJ IDEA】idea修改设置默认maven,解决每次新建和导入项目都需要重新配置maven
【IntelliJ IDEA】idea修改设置默认maven,解决每次新建和导入项目都需要重新配置maven
9826 1
|
JSON 网络协议 Java
云原生(五) | Docker 篇之深入 Dockerfile
Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。 一般而言,Dockerfile可以分为四部分 • 基础镜像信息 • 维护者信息 • 镜像操作指令 • 启动时执行指令
295 0
|
安全
秒懂云通信:号码隐私服务如何保护你的信息安全?
现代人越来越关注个人隐私,对手机号码的保护也越来越看重。通过虚拟中间号来保护真实的手机号码的方式已经被普遍采用,它的通过效果以及感知和日常通话是没有区别的。
3588 0
秒懂云通信:号码隐私服务如何保护你的信息安全?