一、定义

  一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个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的更多相关文章

  1. Java并发之Semaphore的使用

    Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...

  2. Java并发之Semaphore和Exchanger工具类简单介绍

    一.Semaphore介绍 Semaphore意思为信号量,是用来控制同时访问特定资源的线程数数量.它的本质上其实也是一个共享锁.Semaphore可以用于做流量控制,特别是公用资源有限的应用场景.例 ...

  3. Java并发之Semaphore源码解析(二)

    在上一章,我们学习了信号量(Semaphore)是如何请求许可证的,下面我们来看看要如何归还许可证. 可以看到当我们要归还许可证时,不论是调用release()或是release(int permit ...

  4. Java并发之Semaphore源码解析(一)

    Semaphore 前情提要:在学习本章前,需要先了解笔者先前讲解过的ReentrantLock源码解析,ReentrantLock源码解析里介绍的方法有很多是本章的铺垫.下面,我们进入本章正题Sem ...

  5. java并发之(4):Semaphore信号量、CounDownLatch计数锁存器和CyclicBarrier循环栅栏

    简介 java.util.concurrent包是Java 5的一个重大改进,java.util.concurrent包提供了多种线程间同步和通信的机制,比如Executors, Queues, Ti ...

  6. 深入理解Java并发之synchronized实现原理

    深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...

  7. 高并发之Semaphore、Exchanger、LockSupport

    本系列研究总结高并发下的几种同步锁的使用以及之间的区别,分别是:ReentrantLock.CountDownLatch.CyclicBarrier.Phaser.ReadWriteLock.Stam ...

  8. Java并发之AQS原理解读(一)

    前言 本文简要介绍AQS以及其中两个重要概念:state和Node. AQS 抽象队列同步器AQS是java.util.concurrent.locks包下比较核心的类之一,包括AbstractQue ...

  9. java多线程--信号量Semaphore的使用

    Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...

随机推荐

  1. SpriteBuilder中如何简单的重置APP保存的数据

    在任意一款APP中,我们可能需要在磁盘上保存一些游戏数据,以便在下一次运行APP时恢复游戏数据. 但是由于在测试阶段,我们需要快速恢复初始状态的游戏数据,该如何做呢? 非常简单,只需要将APP从真机或 ...

  2. How Tomcat Works 读书笔记 八 载入器 上

    Java的类载入器 详细资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...

  3. LeetCode(30)-Pascal's Triangle

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...

  4. LeetCode(29)-Plus One

    题目: Given a non-negative number represented as an array of digits, plus one to the number. The digit ...

  5. javascript中如何让类工厂和构造函数变成同一个函数

    我们知道在js中可以用一个函数来定义对象的类,该函数称之为对象的构造函数,我们在需要create对象的时候直接调用这个构造函数即可: var Man = funciton(name){ this.na ...

  6. 【图片版】学习CSS网格布局

    简言 CSS网格布局(Grid)是一套二维的页面布局系统,它的出现将完全颠覆页面布局的传统方式.传统的CSS页面布局 一直不够理想.包括table布局.浮动.定位及内联块等方式,从本质上都是Hack的 ...

  7. ssh优缺点

    面试归来 技术面试官叫我谈谈 ssh优缺点 平时用起来倒是挺顺手..但是从来没有系统的总结过..导致很多点会都没有说出来.. 这次我认真总结了一下... 常说的好处 开源 常说的坏处 配置文件过大我就 ...

  8. 什么是shell? bash和shell有什么关系?

    什么是shell? bash和shell有什么关系? 博客分类: Linux   什么是Shell?      shell是你(用户)和Linux(或者更准确的说,是你和Linux内核)之间的接口程序 ...

  9. SQL遇到的问题

    1.问题描述:拼接sql字符串涉及到表变量时报错.  解决办法:把表变量的定义一同放在字符串中. 2.问题描述:EF添加实体后,调用存储过程调用不到 解决办法:必须先db.SaveChanges()后 ...

  10. nginx防盗链

    盗链是指一个网站的资源(图片或附件)未经允许在其它网站提供浏览和下载.尤其热门资源的盗链,对网站带宽的消耗非常大,本文通过nginx的配置指令location来实现简单的图片和其它类型文件的防盗链. ...