一、定义

  一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个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. 尽量用pass-by-reference-to-const(const引用)替换pass-by-value(传值)

    默认情况下C++以pass-by-value传递对象至函数(或从函数返回). eg1: class Person { public: Person(); virtual ~Person(); priv ...

  2. DES

     本文对DES的介绍部分摘自博文DES加密算法的C++实现,具体实现则由自己完成. 另外,DES的官方文档链接见这里,在维基百科上也有比较详细的介绍.不过,DES已经被证明是不安全的(可见于RSA公司 ...

  3. Database Initialization Parameters for Oracle E-Business Suite Release 12

    In This Document Section 1: Common Database Initialization Parameters For All Releases Section 2: Re ...

  4. C语言实现字符串中(10进制和16进制)转成十进制数

    如何将字符串中的10进制数和16进制数提取出来,看以下代码: #include <stdio.h> typedef char TUINT8 ; typedef int TUINT32; T ...

  5. 数据结构---栈C语言实现

    #include <stdio.h> #include <stdlib.h> #define uchar unsigned char #define uint unsigned ...

  6. Linux Framebuffer驱动剖析之一—软件需求

    嵌入式企鹅圈将以本文作为2015年的终结篇,以回应第一篇<Linux字符设备驱动剖析>.嵌入式企鹅圈一直专注于嵌入式Linux和物联网IOT两方面的原创技术分享,稍后会发布嵌入式企鹅圈的2 ...

  7. 配置SharePoint环境加域提示网络名不可用[已解决]

    今天去客户给机器做备机,带着装好SharePoint07的机器跑过去了,先做个LAN,然后连上机器开始工作:首先当然是改ip地址,然后都改好了开始加域,加了好几次,发现都不行,提示"指定的网 ...

  8. PHP基本的语法结构

    学过C语言的话,上手PHP语言就非常快了,如果你有bash shell的基础,那恭喜你,上手PHP会更快,我们先来了解一下一些比较简单的东西,界定符和注释在PHP中的写法: 一 php文档的语法结构 ...

  9. 简单了解AJAX

    // ajax的俩个版本: var xmlhttp; if(window.xmlHttpRequest){ xmlhttp = new xmlHttpRequest(); }else{ xmlhttp ...

  10. jdk1.7 tomcat-7安装

    由于软件下载地址经常有变动,所以不能直接wget,还是直接到网上点击下载 下载jdk http://www.oracle.com/technetwork/java/javase/downloads/j ...