java并发之Semaphore
一、定义
一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可。每个release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。
Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。
二、使用场景代码示例
比方说我们有个资源访问连接池,每次只能同时允许2个线程访问资源,当某个线程或许到资格访问资源业务完成线程结束,它还要自动释放,让其它线程可以访问。
public class Test {
public static void main(String[] args) throws IOException {
ExecutorService executorService = Executors.newCachedThreadPool();
// 配置同时只能有两个线程访问
Semaphore semaphore = new Semaphore(2);
// 开启10个线程
for (int i = 0; i < 10; i++) {
executorService.execute(new TaskRunn(semaphore));
}
// 关闭线程池
executorService.shutdown();
while (true) {
System.out.println(Thread.currentThread().getName()+"semaphore这个信号量中当前可用的许可数:"+semaphore.availablePermits());
System.out.println(Thread.currentThread().getName()+"正在等待获取的线程的估计数目:"+semaphore.getQueueLength());
// System.out.println(Thread.currentThread().getName()+"查询是否有线程正在等待获取:"+semaphore.hasQueuedThreads());
if (semaphore.getQueueLength() == 0) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TaskRunn implements Runnable{
private Semaphore semaphore;
public TaskRunn(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"begin...");
semaphore.acquire();// 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
Thread.sleep(5000);// 模拟业务耗时
semaphore.release();// 释放一个许可,将其返回给信号量
System.out.println(Thread.currentThread().getName()+"end...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
打印信息
mainsemaphore这个信号量中当前可用的许可数:2
main正在等待获取的线程的估计数目:0
pool-1-thread-1begin...
pool-1-thread-2begin...
pool-1-thread-3begin...
pool-1-thread-4begin...
pool-1-thread-5begin...
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:3
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:3
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:3
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:3
pool-1-thread-1end...
pool-1-thread-2end...
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:1
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:1
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:1
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:1
mainsemaphore这个信号量中当前可用的许可数:0
main正在等待获取的线程的估计数目:1
pool-1-thread-3end...
pool-1-thread-4end...
mainsemaphore这个信号量中当前可用的许可数:1
main正在等待获取的线程的估计数目:0
mainsemaphore这个信号量中当前可用的许可数:1
main正在等待获取的线程的估计数目:0
mainsemaphore这个信号量中当前可用的许可数:1
main正在等待获取的线程的估计数目:0
mainsemaphore这个信号量中当前可用的许可数:1
main正在等待获取的线程的估计数目:0
mainsemaphore这个信号量中当前可用的许可数:1
main正在等待获取的线程的估计数目:0
pool-1-thread-5end...
mainsemaphore这个信号量中当前可用的许可数:2
main正在等待获取的线程的估计数目:0
java并发之Semaphore的更多相关文章
- Java并发之Semaphore的使用
Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...
- Java并发之Semaphore和Exchanger工具类简单介绍
一.Semaphore介绍 Semaphore意思为信号量,是用来控制同时访问特定资源的线程数数量.它的本质上其实也是一个共享锁.Semaphore可以用于做流量控制,特别是公用资源有限的应用场景.例 ...
- Java并发之Semaphore源码解析(二)
在上一章,我们学习了信号量(Semaphore)是如何请求许可证的,下面我们来看看要如何归还许可证. 可以看到当我们要归还许可证时,不论是调用release()或是release(int permit ...
- Java并发之Semaphore源码解析(一)
Semaphore 前情提要:在学习本章前,需要先了解笔者先前讲解过的ReentrantLock源码解析,ReentrantLock源码解析里介绍的方法有很多是本章的铺垫.下面,我们进入本章正题Sem ...
- java并发之(4):Semaphore信号量、CounDownLatch计数锁存器和CyclicBarrier循环栅栏
简介 java.util.concurrent包是Java 5的一个重大改进,java.util.concurrent包提供了多种线程间同步和通信的机制,比如Executors, Queues, Ti ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- 高并发之Semaphore、Exchanger、LockSupport
本系列研究总结高并发下的几种同步锁的使用以及之间的区别,分别是:ReentrantLock.CountDownLatch.CyclicBarrier.Phaser.ReadWriteLock.Stam ...
- Java并发之AQS原理解读(一)
前言 本文简要介绍AQS以及其中两个重要概念:state和Node. AQS 抽象队列同步器AQS是java.util.concurrent.locks包下比较核心的类之一,包括AbstractQue ...
- java多线程--信号量Semaphore的使用
Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...
随机推荐
- hadoop学习大纲
- SpriteBuilder修改CCB文件中的子CCB文件需要注意的一个地方
在SpriteBuilder中如果一个CCB(比如一个场景)中嵌入了另一个子CCB文件(比如一个player),那么当给该子CCB中的root对象添加若干属性的时候,必须注意到这个并没有应用到父CCB ...
- Java-ServletRequestListener-ServletRequestAttributeListener
/** * A ServletRequestListener can be implemented by the developer * interested in being notified of ...
- linux打包压缩常用命令
打包: zip gzip bzip2 tar xz //rar zip 包 zip xxx.zip test.c 压缩 unzip xxx.zip ...
- Android特效专辑(十一)——仿水波纹流量球进度条控制器,实现高端大气的主流特效
Android特效专辑(十一)--仿水波纹流球进度条控制器,实现高端大气的主流特效 今天看到一个效果挺不错的,就模仿了下来,加上了一些自己想要的效果,感觉还不错的样子,所以就分享出来了,话不多说,上图 ...
- Github 错误合集:Failed connect to github.com:8080 || Failed connect to github.com:443; No error
文/skay 地址:http://blog.csdn.net/sk719887916/article/details/40541199 开发中遇到github无法pull和push代码问题,原来git ...
- EBS-子库存转移和物料搬运单区别
FROM:http://bbs.erp100.com/forum.php?mod=viewthread&tid=261550&extra=page%3D7 EBS-子库存转移和物料搬运 ...
- objc:NSDateFormatter使用备忘
NSDateFormatter类的实例可以将字符串的日期表示转换为NSDate对象或者反向转换. 如果只要显示日期不需要时间,则可以用-setDateStyle方法来设置显示日期的格式,有以下几种: ...
- android 应用模式之mvp
说到MVP就不得不提到MVC,做过J2EE的猿友们肯定知道MVC是个什么东西.MVC即 Model.View.Controller, 那MVP就Model.View.Presenter.Model用于 ...
- leetcode之旅(10)-Roman to Integer
题目描述: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range fr ...