Semaphore可以用来控制能够同时发给你问某个特定资源的活动的数量或者同时给定操作的数量。计数信号量可以用来实现资源池或者一个容器限定边界。
一个Semaphore管理一个有效许可集合。许可的初始量通过构造函数传递给Semaphore,活动可以获取许可(只要还有剩余的许可),并在使用之后释放许可。获取许可的语法是semaphore.acquire(),如果没有剩余许可,则acquire会被阻塞,release方法向信号量返回一个许可。:
Semaphore semaphore = new Semaphore(1);
表示同时访问资源的许可数量只有一个。这个语义可以实现一个Mutex互斥锁:
package semaphore;
import java.util.concurrent.Semaphore;
/**
*
*<p>Test</p>
*<p>Description:</P>
*<p>Company:Cisco CAS</p>
*<p>Department:CAS</p>
*@Author: Tommy Zhou
*@Since: 1.0
*@Version:Date:2011-4-27
*
**/
public class MutexLock {
private Semaphore semaphore = new Semaphore(1);
/**
* get a permit
* @throws InterruptedException
*/
public void acquire() throws InterruptedException{
semaphore.acquire();
}
/**
* release a permit
* @throws InterruptedException
*/
public void release() throws InterruptedException{
semaphore.release();
}
}
package semaphore;
/**
*
*<p>Test</p>
*<p>Description:</P>
*<p>Company:Cisco CAS</p>
*<p>Department:CAS</p>
*@Author: Tommy Zhou
*@Since: 1.0
*@Version:Date:2011-4-27
*
**/
public class MutexSemaphoreSample {
public static void main(String[] args) {
MutexLock lock = new MutexLock();
new MyThread(lock).start();
new MyThread(lock).start();
}
}
class MyThread extends Thread{
private MutexLock mutex;
public MyThread(MutexLock mutex){
this.mutex = mutex;
}
public void run(){
try {
mutex.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(3000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
try {
mutex.release();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
同样,Semaphore可以轻松实现有界的阻塞容器:
package semaphore;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
/**
*
*<p>Test</p>
*<p>Description:</P>
*<p>Company:Cisco CAS</p>
*<p>Department:CAS</p>
*@Author: Tommy Zhou
*@Since: 1.0
*@Version:Date:2011-4-27
*
**/
public class SemaphoreBlockedList {
private List list;
private Semaphore semaphore;
public SemaphoreBlockedList(int initialSize){
list = new ArrayList(initialSize);
semaphore = new Semaphore(initialSize);
}
public void add(Object o){
try {
semaphore.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
boolean success=list.add(o);
if(!success){
semaphore.release();
}
}
public void remove(Object o){
if(list.remove(o)){
semaphore.release();
}
}
}