java访问并发控制semaphore使用与总结_信号灯控制并发 java_CNXXXPPP的博客-程序员宅基地

技术标签: 并发  访问并发控制  线程调度  java多线程  多线程  semaphore  

semaphore 这个类是用作访问并发控制,可以设置资源最大同时访问的个数。
初始化时参数1 permits(许可数),定义资源可以并发访问的最大个数
例如

public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(3);//资源最多可被3个线程并发访问
        for(int i = 0;i < 20;i++){
            final int threadnum = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("current thread"+Thread.currentThread().getName());
                        semaphore.acquire(1);//获取许可
                        test(threadnum);
                        semaphore.release(1);//释放许可
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        executorService.shutdown();//如果不shutdown工程不会结束
    }

    private static void test(int threadNum) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date())+"  method run "+Thread.currentThread().getName());
        Thread.sleep(1000);
    }

核心方法semaphore.acquire()默认一次获取一个许可,也可以一次获取多个许可,例如semaphore.acquire(3),如果当前可获取的许可数不足,那么当前线程被阻塞。CPU调度其他线程执行。当可以获取到许可时,线程继续执行,当访问需要的资源结束时需要调用semaphore.release(),默认释放一个许可,也可以释放多个许可。如果忘记释放许可,那么当初始化定义的所有许可都被使用完后,其他线程获取不到许可都会处于阻塞状态,程序就无法继续运行。该段代码中我们对test()方法进行了访问并发控制,最大允许3个线程访问执行该方法。
运行结果如下:
这里写图片描述
可以看到test()方法确实每次只有3个线程能执行,其他的都处于阻塞状态。
Semaphore还可以定义是否公平
fair为TRUE时先阻塞的先获得锁
源码实现:

public Semaphore(int permits, boolean fair) {
    sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

semaphore.tryAcquire();尝试获取一个锁,成功返回TRUE失败返回false
代码:

public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(3);//资源最多可被3个线程并发访问
        for(int i = 0;i < 10;i++){
            final int threadnum = i;
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName()+" running");
                      if(semaphore.tryAcquire()){
                          test(threadnum);
                          semaphore.release(1);
                      }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        executorService.shutdown();//如果不shutdown工程不会结束
    }

    private static void test(int threadNum) throws Exception {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date())+"  method run "+Thread.currentThread().getName());
        Thread.sleep(1000);
    }

运行结果:
这里写图片描述
只有3个线程执行了test()方法,其他尝试获取锁失败的线程就丢弃了
还有带参数的tryAcquire方法,第一个参数是等待的时间,第二个是等待时间的单位。
带参数时,方法会在定义的时间内一直尝试获取许可。
semaphore.tryAcquire(2,TimeUnit.SECONDS)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/d597180714/article/details/79961161

智能推荐

测试守护重构_少个分号的博客-程序员宅基地

作为程序员不得不接受的现实是,大多数系统在接手时就已经是遗留系统了。我在最近几年都没有参与新系统开发,不得不接手遗留系统的改造。改造遗留系统的成本实际上比写新的软件要大很多,毕竟就像给高速上飞驰的汽车换轮子。不仅不能引入新的错误,原来的错误在某种程度上也需要“将错就错”,否则对现有用户、现有数据而言顺手修复了一个 bug 反而会带来额外的问题。要想改造遗留系统不是这么简单地事情,需要考虑的事情很多,而测试就是其中很重要的部分。没有单元测试、E2E 测试的系统改造起来难度非常大,所以这也是我热衷于在每个项_测试守护

HTML5 video标签播放视频下载原理_weixin_30339969的博客-程序员宅基地

HTML5 videohttps://github.com/remy/html5demos/blob/master/demos/video.html <video preload="metadata"> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=676422 --> <source sr..._html video source music如何下载

【LeetCode-SQL每日一练】—— 627. 变更性别_sql变更性别_超梦梦梦梦的博客-程序员宅基地

请你编写一个 SQL 查询来交换所有的 'f' 和 'm' (即,将所有 'f' 变为 'm' ,反之亦然),仅使用 单个 update 语句 ,且不产生中间临时表。注意:你必须仅使用一条 update 语句,且 不能 使用 select 语句。_sql变更性别

linux下Nginx配置文件(nginx.conf)配置设置详解(windows用phpstudy集成)_代码成就未来的博客-程序员宅基地

Nginx 虚拟主机配置方法, 本文作为补充也介绍如何 Nginx 上添加虚拟主机。进程列表里 面找master进程,它的编号就是主进程号,每次修改完nginx文件都要重新加载配置文件linux命令,连接超时时间,1分钟,具体时间可以根据请求(例如后台导入)需要的时间来设置。对于来自 FastCGI Server 的 Response,Nginx 将其缓冲到内存中,然后依次发送到客户端浏览器。缓冲区的大小由 fastcgi_buffers 和 fastcgi_buffer_size 两个值控制。

Rootkit的技术发展史_rootkit历史_haoxing168的博客-程序员宅基地

一. 无法驱逐的“助手” 网管小张正在手忙脚乱的寻找他的手工杀毒工具包,因为他在安装一个网管工具的时候无意中走了神,点击了“下一步”按钮后才惊觉安装程序的界面里一个不引人注目的角落里写着“安装CNNIC网络实名”这一行小字,而且最开头部分有一个小小的勾。于是著名的 “中国网民的得力助手”便理所当然的在他的机器里安了家。 心里把厂商骂了十八遍的小张终于翻出了他外出修机_rootkit历史

Vue核心技术-17,组件通过props进行数据验证_vue prop 校验数组里的_BraveWangDev的博客-程序员宅基地

一,前言上一篇介绍了如何通过组件的props选项实现传参这一片将介绍通过props进行参数的数据验证二,props数据验证的使用组件props选项的值可以为为数组类型,也可以是对象类型props选项的对象类型可以用于对外部传递进来的参数进行数据验证当我们封装了一个供他人使用的组件时,对于内部接收的参数进行校验是非常必要的&amp;lt;div id=&quot;app&quot;&amp;gt; ..._vue prop 校验数组里的

随便推点

Hive 并发情况下报 DELETEME 表不存在的异常_hive中不存在该表的数据_张吉Jerry的博客-程序员宅基地

在每天运行的Hive脚本中,偶尔会抛出以下错误:MySQLSyntaxErrorException: Table 'hive.DELETEME1378143540925' doesn't exist_hive中不存在该表的数据

MAP评价指标在faster-rcnn中的使用_faster rcnn显示每个类的map_ff_xun的博客-程序员宅基地

Mean Average Precision(MAP):平均精度均值1.MAP可以由它的三个部分来理解:P,AP,MAPP(Precision)精度,正确率。在信息检索领域用的比较多,和正确率一块出现的是召回率Recall。对于一个查询,返回了一系列的文档,正确率指的是返回的结果中相关的文档占的比例,定义为: precision=返回结果中相关文档的数目/返回结果的数目; 而召回率..._faster rcnn显示每个类的map

一网打尽车载以太网之SOMEIP(上)_someip只用在以太网上啊_汽车小T的博客-程序员宅基地

前言首先,请问大家几个小小问题,你清楚:你知道什么是SOME/IP吗?你知道为什么会产生SOME/IP即相关背景吗?你知道SOME/IP与SOA又有着哪些千丝万缕的联系呢?SOME/IP在实践中到底应该如何使用呢?今天,我们就来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:正文总体介绍正如之前文章<一文入门车载以太网链接>中所介绍的那样,车载以太网协议栈总共可划分为五层,分别为物理层,数据链路层,网络层,传输层,应用层,其中今天所要介绍的内容SOME/_someip只用在以太网上啊

Win系统 - 如何关闭 Hands-Free 模式?_电脑蓝牙连接handsfree模式关闭_放羊的牧码的博客-程序员宅基地

方法 / 步骤设置 - 主页 - 设备 - 往下翻点进去,我这边是B50BT,右键属性选到服务把免提电话服务关闭就好了,不过要在外接一个麦克风,要不然没声。..._电脑蓝牙连接handsfree模式关闭

PHP与sqlite数据库的使用_MrCaptain_Finder的博客-程序员宅基地

$db=new PDO('sqlite:.address/test.db');$db->beginTransaction();$sth = $db->prepare('SELECT * FROM company');$sth->execute();$result = $sth->fetchAll();echo "";print_r($

老罗鸿蒙教程:第5讲-搭建鸿蒙开发环境_鸿蒙开发 openjdk_qfxietian的博客-程序员宅基地

老罗鸿蒙开发系列课程的第5讲:手把手带你搭建鸿蒙开发环境。一、搭建开发环境流程DevEco Studio支持Windows系统和macOS系统,在开发HarmonyOS应用前,您需要准备HarmonyOS应用的开发环境。环境准备流程如下所示:HUAWEI DevEco Studio(获取工具请点击链接下载,以下简称DevEco Studio)是基于IntelliJ IDEA Community开源版本打造,面向华为终端全场景多设备的一站式集成开发环境(IDE),为开发者提供工程模板创.._鸿蒙开发 openjdk

推荐文章

热门文章

相关标签