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. mysql进阶(十九)SQL语句如何精准查找某一时间段的数据

    SQL语句如何精准查找某一时间段的数据 在项目开发过程中,自己需要查询出一定时间段内的交易.故需要在sql查询语句中加入日期时间要素,sql语句如何实现? SELECT * FROM lmapp.lm ...

  2. 【一天一道LeetCode】#328 Odd Even Linked List

    一天一道LeetCode系列 (一)题目 Given a singly linked list, group all odd nodes together followed by the even n ...

  3. 100个Myeclipse6.5免费注册码

    下面提供了100个MyEclipse6.5的注册码供大家使用: register name:cghidigfa Serial:pLR8ZC-855550-6359775146444620 ------ ...

  4. android 之ViewStub

    在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...

  5. Android 的媒体路由功能应用与框架解析

    一.功能描述 Android 的媒体路由API被设计用来允许多种媒体(视频.音乐.图片)在与ANDROID设备连接(无线或有线)的辅助设备(如电视.立体声.家庭戏院系统.音乐播放机)上显示和播放,使用 ...

  6. 【Android 应用开发】Android中的回调Callback

    回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可. 例如给安卓添加按钮点击事件, 我们创建了OnC ...

  7. SpriteBuilder切换解决方案以及CCB的修改与保存

    在SpriteBuilder中切换解决方案非常简单,可以按cmd+数字键即可. 如上图可以看到数字键1,2,3分别对应于3中不同的解决方案. 注意:当通过在CCB中包含一个Sub File Node的 ...

  8. java--加强之 eclipse开发工具

    转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9943899 1.eclipse及IDE开发工具介绍 1.MyEcliose原本是Eclipse ...

  9. linux内核自旋锁API

    我们大概都了解,锁这种机制其实是为了保护临界区代码的,关于使用和定义,我总结的API如下: #include <linux/spinlock.h> 定义自旋锁 spinlock_t loc ...

  10. MySQL数据库存储过程动态表建立(PREPARE)

    PREPARE statement_name FROM sql_text /*定义*/ EXECUTE statement_name [USING variable [,variable...]] / ...