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台机器,那么最多只能提 ...
随机推荐
- SpriteBuilder中CCB精灵对象的Sprite frame为什么有时候不能修改
有时候你会发现CCB中的精灵对象(root节点)的Sprite frame是灰色的,不能修改.因为它是根对象,所以不存在被嵌入其他CCB的情况,那到底是什么原因呢? 可以发现此时的Timeline当前 ...
- java数据类型易错点简单总结,欢迎大神前辈补充!谢谢
数据类型那这边看似简单,花了我很长时间也就是才练到几成"功力"吧.还希望路过的大神在下面补充,菜鸟的我深受感谢! 首先看两个思考题 思考题1:请问下面这个有没有问题 double ...
- Swift之GCD 使用指南2
Grand Central Dispatch大中枢派发:joy: 或俗称 GCD 是一件极其强大的武器.它为你提供了很多底层工具(比如队列和信号量),你可以组合这些工具来实现自己想要的多线程效果.不幸 ...
- Android进阶(十七)AndroidAPP开发问题汇总(一)
首先来看一下猎头公司对于Android方向人才招聘的需求: 猎头公司推荐------资深Java软件工程师(Android方向) 岗位职责: 1.熟悉Java语言,熟悉B/S开发的基本结构 2.能运用 ...
- Linux - quota的举例说明
实作 Quota 流程-1:文件系统支持 [root@www ~]# df -h /home Filesystem Size Used Avail Use% Mounted on /dev/hda3 ...
- Linux常见压缩命令 - gzip,zcat,bzip2,bzcat
几个常见的压缩文件扩展名 *.Z compress 程序压缩的文件: *.gz gzip 程序压缩的文件: *.bz2 bzip2 程序压缩的文件: *.tar tar 程序打包的数据,并没有压缩过: ...
- 使用“万能数据库查询分析器”的Windows 7、Windows 8、Windows 10的用户须知
与以前的Windows操作系统版本(包括WinXP/VISTA/Windows2000/WindowsNt/Win98)不同,Windows 7.Windows 8.Windows 10短日期采用的分 ...
- ZooKeeper leader election
Paxos是分布式应用中解决同步问题的核心.作为应用研发工程师,我们总是倾向于使用一种相对简洁的方式实现复杂的算法.ZooKeeper leader election实现就是一个非常好的参考. 其实现 ...
- MFC中char*,string和CString之间的转换
MFC中char*,string和CString之间的转换 一. 将CString类转换成char*(LPSTR)类型 方法一,使用强制转换.例如: CString theString( &q ...
- windows c/c++ 代码运行时间,毫秒级
#pragma once /* //计算代码段运行时间的类 // */ #include <iostream> #ifndef ComputeTime_h #define ComputeT ...