网站首页 > 精选教程 正文
Semaphore是java并发包里面的一个工具类,我们限制可以访问某些资源的线程数目就可以使用Semaphore了。这篇文章将对Semaphore的概念和使用进行一个详解。
一、概念理解
官方是这样解释的:
Semaphore用于限制可以访问某些资源(物理或逻辑的)的线程数目,他维护了一个许可证集合,有多少资源需要限制就维护多少许可证集合,假如这里有N个资源,那就对应于N个许可证,同一时刻也只能有N个线程访问。一个线程获取许可证就调用acquire方法,用完了释放资源就调用release方法。
不过这样的解释实在有点抽象,现在用我自己的话来解释一下:
相信在学生时代都去餐厅打过饭,假如有3个窗口可以打饭,同一时刻也只能有3名同学打饭。第四个人来了之后就必须在外面等着,只要有打饭的同学好了,就可以去相应的窗口了。
比如说这张图,就全是了Semaphore的基本使用。认识一个知识点的最好方式就是直接去使用,我们干脆直接上代码来看看如何使用。
二、代码使用
这个案例使用的就是我们之前的小例子,也就是去餐厅打饭的案例。
我们先看Test类:
在这个代码中我们看到,主要是new了一个Semaphore,然后赋给每一位同学Student,接下来我们就来好好看看Student线程是如何实现的。
在这个Student类中我们最主要看run方法的实现,首先我们通过acquire获取了当前窗口的许可,然后休眠3秒代表打饭,最后在finally使用release方法释放这个窗口许可证。代码很简单,原理很清楚,我们测试一波:
这个结果你也看到了,基本上同一时刻只能有三个学生在窗口旁边。
在这里你可能有一个疑问了,Semaphore好像和synchronized关键字没什么区别,都可以实现同步,如果是这样那说明我们还没有真正理解jdk的注释,他只是限制了访问某些资源的线程数,其实并没有实现同步,我们可以看一下:
现在我们在获取许可前增加了一条输出语句,也就是能打印出有哪个线程进入了,再去测试一波:
结果很清晰,所以对于Semaphore来说,我们需要记住的其实是资源的互斥而不是资源的同步,在同一时刻是无法保证同步的,但是却可以保证资源的互斥。
三、其他方法
在上面我们使用最基本的acquire方法和release方法就可以实现Semaphore最常见的功能,不过其他方法还是需要我们去了解一下的。
1、acquire(int permits)
从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。就好比是一个学生占两个窗口。这同时也对应了相应的release方法。
2、release(int permits)
释放给定数目的许可,将其返回到信号量。这个是对应于上面的方法,一个学生占几个窗口完事之后还要释放多少
3、availablePermits()
返回此信号量中当前可用的许可数。也就是返回当前还有多少个窗口可用。
4、reducePermits(int reduction)
根据指定的缩减量减小可用许可的数目。
5、hasQueuedThreads()
查询是否有线程正在等待获取资源。
6、getQueueLength()
返回正在等待获取的线程的估计数目。该值仅是估计的数字。
7、tryAcquire(int permits, long timeout, TimeUnit unit)
如果在给定的等待时间内此信号量有可用的所有许可,并且当前线程未被中断,则从此信号量获取给定数目的许可。
8、acquireUninterruptibly(int permits)
从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞。
基本上常见的使用方法都在这,Semaphore底层是由AQS和Uasafe完成的,篇幅问题在这里不赘述了。感谢各位支持。
猜你喜欢
- 2024-11-06 信号量限流,高并发场景不得不说的秘密
- 2024-11-06 面试卡在多线程?那就分享几道Java多线程高频面试题,面试不用愁
- 2024-11-06 Java并发系列之Semaphore源码分析
- 2024-11-06 Java多线程与并发 java的并发,多线程,线程模型
- 2024-11-06 66.java并发编程之Semaphore和CountDownLatch使用
- 2024-11-06 Java基础笔试练习(十五) java基础知识试题
- 2024-11-06 72道Java线程面试题,这些面试官必问
- 2024-11-06 Java并发基础-锁详细分析(可重入锁、读写锁、信号量等)
- 2024-11-06 Java并发工具:CountDownLatch CyclicBarrier Semaphore快速掌握
- 2024-11-06 死磕 java同步系列之Semaphore源码解析
你 发表评论:
欢迎- 最近发表
-
- Python 列表(List)详解
- spring boot Mybatis Mapper.xml使用总结
- Python list列表详解
- Python中获取列表元素数量的方法
- Java List结构转Tree树形结构_非递归_简单优化版
- JAVA进阶知识学习-day02 Collection集合&Iterator迭代器&泛型
- Python列表(List)一文全掌握:核心知识点+20实战练习题
- 踩坑!Java集合必学技能:Collection.size()方法深度解析与避坑
- 深入理解ThreadLocal:线程安全的“独享空间”
- 构建无锁的线程安全架构:掌握Java中ThreadLocal的原理灵活应用
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)