java 信号量Semaphore
Semaphore 信号量主要用于约束多个线程可同时获取的物理上的或者逻辑上的资源数。比如用在各种池的设计中。
信号量用于管理这些资源的一个虚拟的管理凭据。线程在获取一个资源时,首先要获取一个资源的许可凭证。当线程用完之后将资源返回池中,并将许可凭证返回给信号量。
例如:
一个池的例子:
class Pool {
private static final int MAX_AVAILABLE = 100;//最大可用资源数
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
// Not a particularly efficient data structure; just for demo
protected Object[] items = ... whatever kinds of items being managed
protected boolean[] used = new boolean[MAX_AVAILABLE];//是否被使用
protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
return items[i];
}
}
return null; // not reached
}
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
return true;
} else
return false;
}
}
return false;
}
}}
信号量初始化时有两个参数,第一个参数是资源可用数目,第二个是fairness parameter。fairness parameter 是公平变量。设为false那么,当有一个线程请求acquire时,会直接分给这个线程,而不管等待队列中焦急等待的众线程。而公平指的当然就是先来先服务了,如果没获取到一个许可,线程就只好先把自己挂起来了。但是使用tryacquire则直接抢一个许可凭证。调用一个acquire()并不意味着必须调用release(),即java不要求其成对出现,但是保证代码正确,就靠自己的程序设计了。
一下是我自己写的一个信号量的例子:
package com;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;
class Test
{
private final Semaphore sem;
private final Set<String> set;
public Test(int bound)
{
this.set = Collections.synchronizedSet(new HashSet<String>());
this.sem=new Semaphore(bound,true);
}
public boolean add(String str) throws InterruptedException
{
boolean result = false;
sem.acquire();
try{
result=set.add(str);
}finally{
if(!result)
{
sem.release();
}
}
return result;
}
public boolean remove(String str)
{
boolean result=set.remove(str);
if(result)
{
sem.release();
}
return result;
}
}
public class Main{
public static void main(String[] args)
{
Test test = new Test(10);
new Thread(){
public void run()
{
int j=0;
for(int i=20;i<40;)
{
System.out.println("Thread1 run");
try {
test.add(String.valueOf(i));
System.out.println("Thread1 add"+(i++));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Thread1 stop");
}
}.start();
new Thread(){
public void run()
{
int j=0;
boolean result=false;
for(int i=0;i<20;)
{
System.out.println("Thread2 run");
try {
result=test.add(String.valueOf(i));
if(result)System.out.println("Thread2 add"+(i++));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Thread2 stop");
}
}.start();
new Thread(){
public void run()
{
int i=0,j=0;
boolean result=false;
while(i<40)
{
j++;
j=j%40;
System.out.println("Thread3 run");
result=test.remove(String.valueOf(j));
if(result)System.out.println("remove"+(i++));
}
System.out.println("Thread3 stop");
}
}.start();
}
}
java 信号量Semaphore的更多相关文章
- 《转》Java 信号量 Semaphore 介绍
该文章转自:http://www.cnblogs.com/whgw/archive/2011/09/29/2195555.html Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个 ...
- Java信号量Semaphore
Semaphore Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得. Semaphore实现的功能就类似厕所有5个坑,假如有10个人要上厕所,那么同时只能有多少 ...
- Java 信号量 Semaphore 介绍
Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用.Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore可以 ...
- Java信号量 Semaphore 介绍
一.介绍 Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用.Java 并发库 的Semaphore 可以很轻松完成信号量控制,Semaphore ...
- java多线程-Semaphore信号量使用
介绍 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确.合理的使用公共资源. 概念 Semaphore分为单值和多值两种,前者 ...
- 转:【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)
载请注明出处:http://blog.csdn.net/ns_code/article/details/17524153 在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作 ...
- Java中Semaphore(信号量)的使用
Semaphore的作用: 在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了 ...
- java笔记--对信号量Semaphore的理解与运用
java Semaphore 信号量的使用: 在java中,提供了信号量Semaphore的支持. Semaphore类是一个计数信号量,必须由获取它的线程释放, 通常用于限制可以访问某些资源(物理或 ...
- 【Java并发编程】:并发新特性—信号量Semaphore
在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步.当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定 ...
随机推荐
- netconf、yang和XML关系
netconf是基于xml的网络配置协议,文档RFC6241有详细介绍. yang是为netconf建模的一种数据建模语言.文档RFC2060详细介绍了yang1.0版本,RFC7950介绍了yang ...
- 微信公众平台创建自定义菜单的PHP代码
授人以鱼不如授人以渔.在方倍工作室上问了一下,创建自定义菜单的代码多少钱,一张口就一百,好吧,那我就给你们一人省一百块钱吧,你们说该如何谢谢我?事先说明一下啊,你的PHP版本要高于4.0.2才支持cU ...
- 使用pg_buffercache查看缓存区缓存
PG提供了一个扩展pg_buffercache来查看缓存区的内容. create database test; CREATE DATABASE create extension pg_bufferca ...
- NOIP2012junior—P1—质因数分解
NOIP2012junior-P1-质因数分解 时间: 1000ms / 空间: 131072KB [背景] NOIP2012[描述] 已知正整数n 是两个不同的质数的乘积,试求出较大的那个质数. [ ...
- Spring JDBC(二)SimpleJdbcInsert
上一篇写了关于jdbcTemplate的一些基本使用,这一篇来聊聊SimpleJdbcInsert SimpleJdbcInsert是springjdbc提供的一个简化插入操作的类,下面来看一下常用的 ...
- oracle和mysql几点差异对比
Oracle与mysql差异性总结 之前有个项目是用oracle数据库进行开发,需要把数据库改成mysql,遇到了一些地方需要注意的,就简单记了下来. 备注: 再把oracle转成mysql的时候,表 ...
- 阿里Java开发手册1.3.0 文字版
版本: 1.3.0 update: 2017.9.25 一.编程规约 (一) 命名风格 1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例:_name _na ...
- sendGrid 纯文本的换行问题
项目中使用sendGrid发送邮件,并且要求纯文本格式,遇到了无法换行的问题(使用\r\n). 解决方案: 1. 在换行符前加空格(官方推荐的做法 https://sendgrid.com/docs/ ...
- Loadrunner 读取文件
char buffer[1000]; long file_stream; char * filename = "d:\log.txt"; file_stream=fopen(fil ...
- gtk+3.0的环境配置及基于gtk+3.0的python简单样例
/********************************************************************* * Author : Samson * Date ...