首页 > 其他分享 >Semaphore的使用

Semaphore的使用

时间:2023-08-27 17:38:06浏览次数:33  
标签:Thread 队列 Semaphore access 线程 使用 返回值

基本介绍

多线程中上锁的目的一般是一种对受限资源的保护,例如:保证同一时刻只有一个线程能访问的ReentrantLock,或者保证只有一个线程可以写入的ReadWriteLock

还有一种受限资源,它需要保证同一时刻最多有N个线程能访问,比如同一时刻最多创建100个数据库连接,最多允许10个用户下载等

这种限制数量的锁,如果用Lock数组来实现,就太麻烦了。

这种情况就可以使用Semaphore,例如,最多允许2个线程同时访问:

代码测试

public class TestSemaphore {
    public static void main(String[] args) throws InterruptedException {
        AccessLimitControl control = new AccessLimitControl();
        List<Thread> tList = new ArrayList<>();
        for (int i = 0; i< 5; i++) {
            Thread t = new Thread(() -> {
                try {
                    String access = control.access();
                    System.out.println("线程:" + Thread.currentThread().getName() + " 的返回值:" + access);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            tList.add(t);
        }
        for (Thread thread : tList) {
            thread.start();
        }
        for (Thread thread : tList) {
            thread.join();
        }
    }

    static class AccessLimitControl {
        // 任意时刻仅允许最多3个线程获取许可:
        final Semaphore semaphore = new Semaphore(1);
        public String access() throws Exception {
            // 如果超过了许可数量,其他线程将在此等待:
            System.out.println("进入队列的线程:" + Thread.currentThread().getName());
            semaphore.acquire();
            System.out.println("当前线程名称:" + Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
                return UUID.randomUUID().toString();
            } finally {
                semaphore.release();
            }
        }
    }
}

代码运行,以下看似 Thread-3 和 Thread-1 同时进入,其实是 Thread-3 return 后打印结果时,Thread-1 立刻进入了

进入队列的线程:Thread-3
进入队列的线程:Thread-4
进入队列的线程:Thread-1
进入队列的线程:Thread-2
进入队列的线程:Thread-0
当前线程名称:Thread-3
当前线程名称:Thread-1
线程:Thread-3 的返回值:997edc5d-7ec4-4160-a3b7-0d4a76fbb2ff
线程:Thread-1 的返回值:ba87b784-66d0-4073-9967-ccf44df4214a
当前线程名称:Thread-2
线程:Thread-2 的返回值:5c784f8c-fef9-4fa8-83cc-98ee2e7e6238
当前线程名称:Thread-4
线程:Thread-4 的返回值:376938f5-98ab-49da-9402-566523f31ed0
当前线程名称:Thread-0
线程:Thread-0 的返回值:f51391af-649a-404a-a2d7-68b073d44ec0

小结

Semaphore本质上就是一个信号计数器,用于限制同一时间的最大访问数量,如果要对某一受限资源进行限流访问,可以使用Semaphore,保证同一时间最多N个线程访问受限资源。

标签:Thread,队列,Semaphore,access,线程,使用,返回值
From: https://blog.51cto.com/u_11354383/7253605

相关文章

  • Tkinter 列表控件Listbox使用
    1、使用StringVar初始化数据fromtkinterimport*importgjutil#初始化窗口root=Tk()root.title('listboxdemo')root.geometry(gjutil.getGeometry(root))#初始化数据array_lang_data=['python','golang','kotlin','dart......
  • vue微信H5项目使用腾讯地图获取当前位置经纬度
    1.在index.html引入js文件<scriptsrc="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>2.在需要页面中你自己的key要去腾讯地图工具去申请https://lbs.qq.com/webApi/component/componentGuide/componentPickercreated(){this.getM......
  • Makefile练习1:静态库/动态库的生成和使用
    自己动手写下Makefile,并记录备忘。工程目录如下一、生成静态库libAdd.a1、头文件add.h#include<stdio.h>intadd(inta,intb);2、源文件add.c#include"add.h"intadd(inta,intb){ return(a+b);}3、Makefile(1)入门版libAdd.a:add.o ar-rlibAdd.aad......
  • 求求你不要在使用BeanUtils进行拷贝了
    哈喽,大家好,我是指北君。最近接手一个项目发现有些接口只是做了一些简单的单表查询业务,但是却耗时八百多毫秒,明显不太正常,经排查发现时间都消耗在Apache的BeanUtils中对属性的拷贝上,整个流程使用了四次拷贝方法,使得整个方法耗时急剧增加。指北君在这里求求大家不要再使用BeanUtils......
  • 安装及使用Nginx
    一、安装及使用Nginx1编译安装nginxcontrib:vim格式文件,修改nginx配置文件的格式,高亮cp-r/opt/nginx-1.18.0/contrib/vim/*/usr/share/vim/vimfiles/conf:配置文件man:man帮助manman/nginx.8不加路径看不了nginx.8文件src:源码包点c点h结尾的文件findsrc......
  • Java中MongoDB的mongoTemplate使用(增删改查)
    注:本文只讲在java中的使用,并且只简单讲一下本人在开发中遇到的一部分并不完全概括在cmd中的请自行查看其他博主.简单准备:想用它就得引入它:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb......
  • 使用 OpenTelemetry 构建 .NET 应用可观测性(1):什么是可观测性
    目录什么是系统的可观测性(Observability)为什么需要软件系统需要可观测性可观测性的三大支柱日志(Logging)指标(Metrics)分布式追踪(DistributedTracing)Trace和SpanUnknowUnknowsVSKnownUnknowns数据的关联-实现可观测性的关键总结什么是系统的可观测性(Observability)对软件行......
  • 使用Apache IoTDB进行IoT相关开发的架构设计与功能实现(10)
    所有参数的详细说明见表3-5。表3-5线性填充参数列表参数名称(不区分大小写)解释路径,前缀路径查询路径;必填项T查询时间戳(只能指定一个);必填项data_type填充方法使用的数据类型。可选值为int32、int64、浮点型、双精度型、布尔值、文本;可选字段before_range,after_range表示线性方......
  • Facechain使用教程:3张照片就能生成个人写真,还完全免费
    1.效果展示下面4张图片,小伙伴们有没有看出来哪些是原图,哪些是AI生成的呢?上面的图片第1张是原图,其他的都是AI生成的哦~今天来教大家怎么用facechain训练自己的人物写真模型,然后就可以尝试各种风格的照片了。2.Facechain说明准备工作:Facechain了解一下,地址:https://github.com/modelsc......
  • mormot2 笔记(四) Services的使用
    constructorTMyRestServer.Create(Port:Word);begininheritedCreate;FRestServerDB:=TRestServerDB.Create(TOrmModelFactory.ModelInstance,SQLITE_MEMORY_DATABASE_NAME);FRestServerDB.DB.Synchronous:=smOff;FRestServerDB.DB.LockingMode:=lmExc......