Java多线程-新特征-信号量Semaphore
简介
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。
概念
Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
以一个停车场运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
更进一步,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。 当一个线程调用Wait(等待)操作时,它要么通过然后将信号量减一,要么一直等下去,直到信号量大于一或超时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为加操作实际上是释放了由信号量守护的资源。
在java中,还可以设置该信号量是否采用公平模式,如果以公平方式执行,则线程将会按到达的顺序(FIFO)执行,如果是非公平,则可以后请求的有可能排在队列的头部。
JDK中定义如下:
Semaphore(int permits, boolean fair)
创建具有给定的许可数和给定的公平设置的Semaphore。
Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用。Java并发库Semaphore 可以很轻松完成信号量控制,Semaphore可以控制某个资源可被同时访问的个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。比如在Windows下可以设置共享文件的最大客户端访问个数。
Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少个人去上厕所呢?同时只能有5个人能够占用,当5个人中 的任何一个人让开后,其中等待的另外5个人中又有一个人可以占用了。另外等待的5个人中可以是随机获得优先机会,也可以是按照先来后到的顺序获得机会,这取决于构造Semaphore对象时传入的参数选项。单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。
package cn.thread; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore; /**
* 信号量
*
* @author 林计钦
* @version 1.0 2013-7-25 下午02:03:40
*/
public class SemaphoreTest {
public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
// 模拟20个客户端访问
for (int index = 0; index < 50; index++) {
final int NO = index;
Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
// 访问完后,释放
semp.release();
//availablePermits()指的是当前信号灯库中有多少个可以被使用
System.out.println("-----------------" + semp.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
}
}
Accessing: 0
Accessing: 1
Accessing: 2
Accessing: 4
Accessing: 6
Accessing: 8
-----------------0
-----------------1
Accessing: 3
-----------------1
Accessing: 5
Accessing: 9
-----------------0
-----------------1
Accessing: 7
Accessing: 10
-----------------0
-----------------1
Accessing: 11
-----------------1
Accessing: 12
-----------------1
Accessing: 13
Accessing: 14
-----------------0
-----------------1
Accessing: 15
-----------------0
Accessing: 16
-----------------1
Accessing: 17
-----------------1
Accessing: 18
-----------------1
Accessing: 19
-----------------0
Accessing: 20
Accessing: 21
-----------------0
Accessing: 22
-----------------0
-----------------1
Accessing: 23
-----------------1
Accessing: 24
-----------------0
Accessing: 25
Accessing: 26
-----------------0
-----------------1
Accessing: 27
-----------------1
Accessing: 28
-----------------1
Accessing: 29
Accessing: 30
-----------------0
-----------------1
Accessing: 31
-----------------1
Accessing: 32
-----------------1
Accessing: 33
-----------------1
Accessing: 34
Accessing: 35
-----------------0
-----------------1
Accessing: 36
-----------------1
Accessing: 37
-----------------1
Accessing: 38
-----------------1
Accessing: 39
-----------------1
Accessing: 40
Accessing: 41
-----------------0
-----------------1
Accessing: 42
Accessing: 43
-----------------0
Accessing: 44
-----------------0
-----------------1
Accessing: 45
-----------------1
Accessing: 46
-----------------1
Accessing: 47
-----------------1
Accessing: 48
-----------------1
Accessing: 49
-----------------1
-----------------2
-----------------3
-----------------4
-----------------5
Java多线程-新特征-信号量Semaphore的更多相关文章
- Java多线程-新特征-阻塞队列ArrayBlockingQueue
阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...
- Java多线程-新特征-阻塞栈LinkedBlockingDeque
对于阻塞栈,与阻塞队列相似.不同点在于栈是“后入先出”的结构,每次操作的是栈顶,而队列是“先进先出”的结构,每次操作的是队列头. 这里要特别说明一点的是,阻塞栈是Java6的新特征.. Java为阻塞 ...
- Java多线程-新特征-原子量
所谓的原子量即操作变量的操作是“原子的”,该操作不可再分,因此是线程安全的. 为何要使用原子变量呢,原因是多个线程对单个变量操作也会引起一些问题.在Java5之前,可以通过volatile.synch ...
- Java多线程-新特征-锁(上)
在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的封锁,用来控制对竞争资源并发访问的控制,这些内容主要集中在java.util.concurrent.locks 包下面,里面有三个重要的接口 ...
- Java多线程-新特征-锁(下)
在上文中提到了Lock接口以及对象,使用它,很优雅的控制了竞争资源的安全访问,但是这种锁不区分读写,称这种锁为普通锁.为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控 ...
- Java多线程-新特征-锁
Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock,详细的API可以查看JavaAPI ...
- 转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)
载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153 在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作 ...
- 【Java并发编程】:并发新特性—信号量Semaphore
在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步.当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定 ...
- Java线程新特征——Java并发库
一.线程池 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...
随机推荐
- Android系统自带分享功能的实现(可同时分享文字和图片)
/** * 分享功能 * * @param context * 上下文 * @param activityTitle * Activity的名字 * @param msgTitle * 消息标题 ...
- Azure VM Scalable Sets -- 适用IAAS架构
1. 选择Virtual Machine scale set2. 选择resource manager(或创建最新)3. 基本信息配置4. 配置scale的参数(可伸缩的balance模型):VM最小 ...
- Leetcode 912. Sort an Array
class Solution: def sortArray(self, nums: List[int]) -> List[int]: return sorted(nums)
- python学习之函数和函数参数
#方法的参数定义和默认参数的定义 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while True: ok = inp ...
- 高级C/C++编译技术之读书笔记(四)之定位库文件
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- WPF XMAL获取元素的父元素,子元素
/// 获得指定元素的父元素 /// </summary> /// <typeparam name="T">指定页面元素</typeparam> ...
- The last packet sent successfully to the server was 0 milliseconds ago
出现异常”The last packet sent successfully to the server was 0 milliseconds ago.“的大部分原因是由于数据库回收了连接,而系统的缓 ...
- Java中小数保留问题
方式一: 四舍五入 double f = 111231.5585; BigDecimal b = new BigDecimal(f); double f1 ...
- CentOS7 配置光盘iso镜像为本地yum源
因为系统使用的最小化安装,所以很多软件没有安装上,又无法上网,为了方便,所以直接将上传的iso镜像直接作为yum源. 我已经将光盘的iso镜像上传至服务器. 接下来就是将iso的光盘镜像进行挂载了 m ...
- Oracle Sql Developer 连接 SqlServer
1.下载 jTDS - SQL Server and Sybase JDBC driver 地址:http://sourceforge.net/projects/jtds/files/ 2.运行SQL ...