Java并发编程之Semaphore详解

 更新时间:2023年12月31日 08:13:54   作者:_Romeo  
这篇文章主要介绍了Java并发编程之concurrent包中的Semaphore详解,信号量Semaphore一般用来表示可用资源的个数,相当于一个计数器,可类比生活中停车场牌子上面显示的停车场剩余车位数量,需要的朋友可以参考下

概念

  • 信号量Semaphore一般用来表示可用资源的个数,相当于一个计数器,可类比生活中停车场牌子上面显示的停车场剩余车位数量。
  • 当有车开进去的时候, 就相当于申请一个可用资源,可用车位就 -1 (这个称为信号量的 P 操作) 当有车开出来的时候, 就相当于释放一个可用资源, 可用车位就 +1 (这个称为信号量的 V 操作)
  • 如果计数器的值已经为 0 了,还尝试申请资源,就会阻塞等待,直到有其他线程释放资源(计数器的值是大于等于0的)

默认构造方法

 public Semaphore(int permits){}

信号量:permits

重要方法

//申请资源,计数器值=0,则阻塞
public void acquire() throws InterruptedException {}
//释放资源
public void release() {}

1、类Semaphore的构造函数permits 是许可的意思,代表同一时间,最多允许permits执行acquire() 和release() 之间的代码。

例如:

Semaphore semaphore = new Semaphore(1);
  • 2、方法acquire(n) 的功能是每调用1次此方法,就消耗掉n个许可。
  • 3、方法release(n) 的功能是每调用1次此方法,就动态添加n个许可。
  • 4、方法acquireUnnterruptibly()作用是是等待进入acquire() 方法的线程不允许被中断。
  • 5、方法availablePermits() 返回Semaphore对象中当前可以用的许可数。
  • 6、方法drainPermits() 获取并返回所有的许可个数,并且将可用的许可重置为0
  • 7、方法 getQueueLength() 的作用是取得等待的许可的线程个数
  • 8、方法 hasQueueThreads() 的作用是判断有没有线程在等待这个许可
  • 9、公平和非公平信号量:有些时候获取许可的的顺序与线程启动的顺序有关,这是的信号量就要分为公平和非公平的。所谓的公平信号量是获得锁的顺序与线程启动的顺序有关,但不代表100%获得信号量,仅仅是在概率上能保证,而非公平信号量就是无关的。

例如:

Semaphore semaphore = new Semaphore(1,false);
  • False:表示非公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序无关,也就是线程先启动了并不代表先获得 许可。
  • True:公平信号量,即线程启动的顺序与调用semaphore.acquire() 的顺序有关,也就是先启动的线程优先获得许可。
  • 10、方法tryAcquire() 的作用是尝试获取1个许可。如果获取不到则返回false,通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可以使不至于在同步处于一直持续等待的状态。
  • 11、方法tryAcquire(n) 的作用是尝试获取n个许可,如果获取不到则返回false
  • 12、方法tryAcquire(long timeout,TimeUnit unit)的作用是在指定的时间内尝试获取1个许可,如果获取不到则返回false
  • 13、方法tryAcquire(int permits,long timeout,TimeUnit unit) 的作用是在指定的时间内尝试获取n 个许可,如果获取不到则返回false
  • 14、多进路-多处理-多出路:允许多个线程同时处理任务

测试使用

import java.util.concurrent.Semaphore;
public class Test {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("准备申请资源");
                    semaphore.acquire();
                    System.out.println("申请资源成功");
                    // 申请到资源之后休眠1秒
                    Thread.sleep(1000);
                    semaphore.release();
                    // 释放资源
                    System.out.println("释放资源完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        // 创建15个线程,让这 15 个线程来分别去尝试申请资源
        for (int i = 0; i < 15; i++) {
            Thread t = new Thread(runnable);
            t.start();
        }
    }
}

运行结果如下:

在这里插入图片描述

可以看到,由于资源数为3,所以前3个线程申请资源后很容易成功,而之后的线程就没有资源可以申请了,只能等到前3个线程把资源释放出来后再申请

信号量相当于是锁的升级版本,锁只能控制一个资源的有无,而信号量可以控制很多个资源的有无

到此这篇关于Java并发编程之concurrent包中的Semaphore详解的文章就介绍到这了,更多相关Java的Semaphore信号量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java语言中&&与& ||与|的区别是什么

    Java语言中&&与& ||与|的区别是什么

    这篇文章主要介绍了Java语言中&&与& ||与|的区别是什么的相关资料,需要的朋友可以参考下
    2017-04-04
  • 解决偶现的MissingServletRequestParameterException异常问题

    解决偶现的MissingServletRequestParameterException异常问题

    这篇文章主要介绍了解决偶现的MissingServletRequestParameterException问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 深入理解Java运行时数据区_动力节点Java学院整理

    深入理解Java运行时数据区_动力节点Java学院整理

    这篇文章主要介绍了Java运行时数据区的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-06-06
  • 解析java稀疏数组如何帮助我们节省内存提升性能

    解析java稀疏数组如何帮助我们节省内存提升性能

    这篇文章主要为大家介绍了java稀疏数组如何帮助我们节省内存提升性能解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java设计模式之备忘录模式_动力节点Java学院

    Java设计模式之备忘录模式_动力节点Java学院

    我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态。接下来通过本文给大家分享java设计模式之备忘录模式,感兴趣的的朋友一起看看吧
    2017-08-08
  • Java spring AOP基础

    Java spring AOP基础

    本篇文章主要介绍了深入理解spring的AOP机制基础原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-11-11
  • spring mvc DispatcherServlet之前端控制器架构详解

    spring mvc DispatcherServlet之前端控制器架构详解

    这篇文章主要为大家详细介绍了spring mvc DispatcherServlet之前端控制器架构,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • Java实现获取cpu、内存、硬盘、网络等信息的方法示例

    Java实现获取cpu、内存、硬盘、网络等信息的方法示例

    这篇文章主要介绍了Java实现获取cpu、内存、硬盘、网络等信息的方法,涉及java使用第三方jar包针对本机硬件的cpu、内存、硬盘、网络信息等的读取相关操作技巧,需要的朋友可以参考下
    2018-06-06
  • spring如何解决循环依赖问题详解

    spring如何解决循环依赖问题详解

    这篇文章主要给大家介绍了关于spring如何解决循环依赖问题的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java实现List反转的方法总结

    Java实现List反转的方法总结

    在Java中,反转一个List意味着将其元素的顺序颠倒,使得第一个元素变成最后一个,最后一个元素变成第一个,依此类推,这一操作在处理数据集合时非常有用,所以本文给大家总结了Java实现List反转的方法,需要的朋友可以参考下
    2024-04-04

最新评论