Semaphore可以维护当前访问自身的线程个数,并且提供了同步机制。

  Semaphore实现的功能类似于厕所里有5个坑,有10个人要上厕所,同时就只能有5个人占用,当5个人中 的任何一个让开后,其中在等待的另外5个人中又有一个可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项(常见于 限流 机制场景应用中):

  Semaphore(int permits)

  Semaphore(int permits, boolean fair)

  JDK包位置:java.util.concurrent.Semaphore

  一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。

  Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问:

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; public class SemaphoreTest {
public static void main(String[] args) {
//线程数动态变化,来一个就产生一个线程
ExecutorService service = Executors.newCachedThreadPool();
//可容纳的线程并发数
final Semaphore sp = new Semaphore(3);
for (int i = 0; i < 10; i++) {
Runnable runnable = new Runnable() {
public void run() {
try {
//从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
sp.acquire();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(String.format("线程%s进入,当前已有%d个并发", Thread.currentThread().getName(), (3 - sp.availablePermits())));
try {
Thread.sleep((long) (Math.random() * 10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("线程【%s】已经离开-------BYE BYE", Thread.currentThread().getName()));
sp.release();//释放一个许可,将其返回给信号量
}
};
service.execute(runnable);//提交了10个任务放入到线程队列
}
try {
while (true) {
if (sp.availablePermits() == 3) {
System.out.println("****************所有线程执行完毕****************");
break;
}
}
} finally {
service.shutdown();
}
}
}

上述代码运行结果如下所示:

  

  总结:传统互斥只能内部释放锁this.unlock(),进去this.lock()晕倒了别人就没法进去了;单个信号量的Semaphore对象也可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,sp.release()  sp.acquire()。这可应用于死锁恢复的一些场合

提示:欢迎继续参看我相关的下一篇博客:并发库应用之八 & 循环路障CyclicBarrier应用

并发库应用之七 & 信号灯Semaphore应用的更多相关文章

  1. 并发库应用之六 & 有条件阻塞Condition应用

    Condition的功能类似在传统线程技术中的 Object.wait() 和 Object.natify() 的功能,传统线程技术实现的互斥只能一个线程单独干,不能说这个线程干完了通知另一个线程来干 ...

  2. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  3. 【java并发】线程同步工具Semaphore的使用

    Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,我们可以自己设定最大访问量.它有两个很常用的方法是acquire()和release(),分别是获得许可和释放许可.  官方J ...

  4. 并发库应用之十一 & 阻塞队列的应用

    队列包含固定长度的队列和不固定长度的队列,队列的规则就是:先进先出.固定长度的队列往里放数据,如果放满了还要放,阻塞式队列就会等待,直到有数据取出,空出位置后才继续放:非阻塞式队列不能等待就只能报错了 ...

  5. 并发-CountDownLatch、CyclicBarrier和Semaphore

    CountDownLatch.CyclicBarrier和Semaphore 参考: http://www.cnblogs.com/dolphin0520/p/3920397.html https:/ ...

  6. Java多线程与并发库高级应用-java5线程并发库

    java5 中的线程并发库 主要在java.util.concurrent包中 还有 java.util.concurrent.atomic子包和java.util.concurrent.lock子包 ...

  7. java并发库_并发库知识点整理

    并发库(java.util.concurrent)中的工具数不胜数,那么我们梳理一下线程并发库中重要的一些常用工具: 1.

  8. 线程高级应用-心得8-java5线程并发库中同步集合Collections工具类的应用及案例分析

    1.  HashSet与HashMap的联系与区别? 区别:前者是单列后者是双列,就是hashmap有键有值,hashset只有键: 联系:HashSet的底层就是HashMap,可以参考HashSe ...

  9. 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

    1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...

随机推荐

  1. PDA智能设备解决方案打包及部署

    演练:打包智能设备解决方案以便进行部署 Visual Studio 2008 本演练演示如何使用 Visual Studio 将应用程序及其资源打包到一个 CAB 文件中,以便可将其部署到最终用户的智 ...

  2. SVM实验

    说明: 1)α2=0表示第二个样例不在分类面上,在分类面上的点αi均不为零. 2)二次项矩阵,可以通过矩阵相乘相加方法得到,如上例 3)目标函数变为负值,是为了照顾matlab的标准型. 假定应用多项 ...

  3. Android中的Message机制

    对于Android的Message机制主要涉及到三个主要的类,分别是Handler.Message.Looper:首先对每个类做一个简单介绍:然后再介绍所谓的Android的Message机制是如何实 ...

  4. GCC/gcc/g++/CC/cc区别

    平常在Linux上经常会用到gcc或者g++来编译程序,但对这两者的理解也就停留在一个是用来编译C程序,另一个是用来编译C++程序的(请注意:这种说法是有问题的,待会改进). 1. GCC GCC,是 ...

  5. Erlang cowboy 处理简单的HTTP请求

    Erlang cowboy 处理简单的HTTP请求 原文出自: Handling plain HTTP requests 处理请求的最简单的方式是写一个简单的HTTP处理器.它的模型参照Erlang/ ...

  6. Global Financial Applications uses the following Public tables

    来自文档: Oracle  Financial Applications Technical Reference Manual  更多明细参考文档 Table Name                 ...

  7. Mybatis源码之CallableStatementHandler

    /** * @author Clinton Begin */ public class CallableStatementHandler extends BaseStatementHandler { ...

  8. Linux input子系统分析

    输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分 ...

  9. mysql基础优化-explain的使用-mysql死锁

    MySQL的优化 主要包括三个方面,首先是SQL语句的优化,其次是表结构的优化(这里主要指索引的优化),最后是服务器配置的优化. 一.SQL语句的优化 在 where 及 order by 涉及的列上 ...

  10. jQuery插件之----缓冲运动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...