?????技术信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个特定操作的数量。计数信号量还可以用来实现某种资源池或者对容器加边界。
??Semaphore中管理着一组虚拟许可(permit),许可的初始数量可以通过在构造方法中指定。在执行操作时首先获取许可(permit),在使用完成后释放许可。如果没有许可,那么acquire则一直阻塞到有许可或者超时中断。
?
/**
* 计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个指定操作的数量。
* 计数信号量还可以用来实现某种资源池或者对容器进行加边界
* Semaphore 中管理着一组虚拟的许可(permit),许可的初始化数量可以通过构造函数来指定。在执行操作时可以
* 首先获取许可(只要还有剩余的许可),并在使用后释放许可(permit)。 如果没有许可(permit)那么aquire将阻塞
* 直到有许可或者直到被中断、操作超时。release方法将释放一个许可,返回给信号量(semaphore)
*
* @author zhangwei_david
* @version $Id: BoundedHashSet.java, v 0.1 2014年11月11日 下午1:49:24 zhangwei_david Exp $
*/
public class BoundedHashSet<T> {
//
private final Set<T> set;
// 信号量
private final Semaphore sem;
public BoundedHashSet(int bound) {
//初始化一个同步Set
this.set = Collections.synchronizedSet(new HashSet<T>());
//初始化信号量大小
sem = new Semaphore(bound);
}
public boolean add(T o) throws InterruptedException {
// 获取许可
sem.acquire();
System.out.println("获取许可 " + sem.availablePermits());
boolean wasAdded = false;
try {
wasAdded = set.add(o);
return wasAdded;
} finally {
if (!wasAdded) {
// 如果增加失败
System.out.println("添加失败,释放许可");
sem.release();
}
}
}
public boolean remove(Object o) {
boolean wasRemoved = set.remove(o);
if (wasRemoved) {
// 删除后释放许可
System.out.println("删除成功,释放许可");
sem.release();
}
return wasRemoved;
}
}
?
?
/**
* 资源池
* @author zhangwei_david
* @version $Id: ResourcePool.java, v 0.1 2015年7月5日 上午9:53:18 zhangwei_david Exp $
*/
public class ResourcePool<T> {
private int size;
private List<T> items = new ArrayList<T>();
private volatile boolean[] checkOut;
private Semaphore available;
public ResourcePool(Class<T> clazz, int max) {
size = max;
checkOut = new boolean[size];
available = new Semaphore(size);
for (int i = 0; i < size; i++) {
try {
items.add(clazz.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public T checkOut() throws InterruptedException {
available.acquire();
return getItem();
}
public void checkIn(T t) {
if (releaseItem(t)) {
available.release();
}
}
/**
* 释放对象,如果该对象在对象池中不存在则返回false
* 如果该对象尚未被checkOut则返回fasle
* 将checkOut标准置为false,返回true
*
* @param t
* @return
*/
private synchronized boolean releaseItem(T t) {
int index = items.indexOf(t);
if (index == -1) {
return false;
}
if (checkOut[index]) {
checkOut[index] = false;
return true;
}
return false;
}
/**6
* 如果还有对象没有checkOut则返回该对象,如果没有则返回null
*
* @return
*/
private synchronized T getItem() {
for (int i = 0; i < size; i++) {
if (!checkOut[i]) {
checkOut[i] = true;
return items.get(i);
}
}
return null;
}
}
?
?
/**
*
* @author zhangwei_david
* @version $Id: Link.java, v 0.1 2015年7月5日 上午10:11:03 zhangwei_david Exp $
*/
public class Link {
private static int counter = 0;
private final int id = counter++;
public Link() {
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (Exception e) {
}
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Link [ id=" + id + "]";
}
}
?
/**
*
* @author zhangwei_david
* @version $Id: SemaphoreDemo.java, v 0.1 2015年7月5日 上午10:20:16 zhangwei_david Exp $
*/
public class SemaphoreDemo {
/**
*
* @param args
*/
public static void main(String[] args) {
final ResourcePool<Link> linkes = new ResourcePool<Link>(Link.class, 30);
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 60; i++) {
exec.execute(new CheckOutTask<Link>(linkes));
}
exec.shutdown();
}
}
?
CheckOutTask [id=0] check out Link [ id=0] CheckOutTask [id=1] check out Link [ id=1] CheckOutTask [id=3] check out Link [ id=2] CheckOutTask [id=2] check out Link [ id=3] CheckOutTask [id=4] check out Link [ id=4] CheckOutTask [id=6] check out Link [ id=5] CheckOutTask [id=5] check out Link [ id=6] CheckOutTask [id=7] check out Link [ id=7] CheckOutTask [id=8] check out Link [ id=8] CheckOutTask [id=9] check out Link [ id=9] CheckOutTask [id=10] check out Link [ id=10] CheckOutTask [id=11] check out Link [ id=11] CheckOutTask [id=12] check out Link [ id=12] CheckOutTask [id=13] check out Link [ id=13] CheckOutTask [id=14] check out Link [ id=14] CheckOutTask [id=15] check out Link [ id=15] CheckOutTask [id=16] check out Link [ id=16] CheckOutTask [id=17] check out Link [ id=17] CheckOutTask [id=18] check out Link [ id=18] CheckOutTask [id=19] check out Link [ id=19] CheckOutTask [id=20] check out Link [ id=20] CheckOutTask [id=21] check out Link [ id=21] CheckOutTask [id=22] check out Link [ id=22] CheckOutTask [id=23] check out Link [ id=23] CheckOutTask [id=24] check out Link [ id=24] CheckOutTask [id=25] check out Link [ id=25] CheckOutTask [id=26] check out Link [ id=26] CheckOutTask [id=27] check out Link [ id=27] CheckOutTask [id=28] check out Link [ id=28] CheckOutTask [id=29] check out Link [ id=29] CheckOutTask [id=2] check in Link [ id=3] CheckOutTask [id=1] check in Link [ id=1] CheckOutTask [id=3] check in Link [ id=2] CheckOutTask [id=4] check in Link [ id=4] CheckOutTask [id=31] check out Link [ id=1] CheckOutTask [id=30] check out Link [ id=2] CheckOutTask [id=32] check out Link [ id=3] CheckOutTask [id=33] check out Link [ id=4] CheckOutTask [id=0] check in Link [ id=0] CheckOutTask [id=34] check out Link [ id=0] CheckOutTask [id=10] check in Link [ id=10] CheckOutTask [id=15] check in Link [ id=15] CheckOutTask [id=18] check in Link [ id=18] CheckOutTask [id=12] check in Link [ id=12] CheckOutTask [id=16] check in Link [ id=16] CheckOutTask [id=14] check in Link [ id=14] CheckOutTask [id=19] check in Link [ id=19] CheckOutTask [id=5] check in Link [ id=6] CheckOutTask [id=7] check in Link [ id=7] CheckOutTask [id=9] check in Link [ id=9] CheckOutTask [id=17] check in Link [ id=17] CheckOutTask [id=37] check out Link [ id=7] CheckOutTask [id=36] check out Link [ id=6] CheckOutTask [id=35] check out Link [ id=10] CheckOutTask [id=8] check in Link [ id=8] CheckOutTask [id=40] check out Link [ id=14] CheckOutTask [id=6] check in Link [ id=5] CheckOutTask [id=42] check out Link [ id=15] CheckOutTask [id=43] check out Link [ id=5] CheckOutTask [id=44] check out Link [ id=16] CheckOutTask [id=47] check out Link [ id=17] CheckOutTask [id=45] check out Link [ id=18] CheckOutTask [id=13] check in Link [ id=13] CheckOutTask [id=11] check in Link [ id=11] CheckOutTask [id=26] check in Link [ id=26] CheckOutTask [id=55] check out Link [ id=13] CheckOutTask [id=53] check out Link [ id=19] CheckOutTask [id=56] check out Link [ id=26] CheckOutTask [id=27] check in Link [ id=27] CheckOutTask [id=41] check out Link [ id=8] CheckOutTask [id=39] check out Link [ id=12] CheckOutTask [id=38] check out Link [ id=9] CheckOutTask [id=54] check out Link [ id=27] CheckOutTask [id=52] check out Link [ id=11] CheckOutTask [id=24] check in Link [ id=24] CheckOutTask [id=25] check in Link [ id=25] CheckOutTask [id=23] check in Link [ id=23] CheckOutTask [id=57] check out Link [ id=23] CheckOutTask [id=58] check out Link [ id=24] CheckOutTask [id=50] check out Link [ id=25] CheckOutTask [id=22] check in Link [ id=22] CheckOutTask [id=21] check in Link [ id=21] CheckOutTask [id=59] check out Link [ id=21] CheckOutTask [id=20] check in Link [ id=20] CheckOutTask [id=46] check out Link [ id=22] CheckOutTask [id=51] check out Link [ id=20] CheckOutTask [id=29] check in Link [ id=29] CheckOutTask [id=49] check out Link [ id=29] CheckOutTask [id=28] check in Link [ id=28] CheckOutTask [id=48] check out Link [ id=28] CheckOutTask [id=30] check in Link [ id=2] CheckOutTask [id=33] check in Link [ id=4] CheckOutTask [id=32] check in Link [ id=3] CheckOutTask [id=31] check in Link [ id=1] CheckOutTask [id=34] check in Link [ id=0] CheckOutTask [id=45] check in Link [ id=18] CheckOutTask [id=37] check in Link [ id=7] CheckOutTask [id=36] check in Link [ id=6] CheckOutTask [id=40] check in Link [ id=14] CheckOutTask [id=42] check in Link [ id=15] CheckOutTask [id=35] check in Link [ id=10] CheckOutTask [id=43] check in Link [ id=5] CheckOutTask [id=47] check in Link [ id=17] CheckOutTask [id=44] check in Link [ id=16] CheckOutTask [id=59] check in Link [ id=21] CheckOutTask [id=46] check in Link [ id=22] CheckOutTask [id=50] check in Link [ id=25] CheckOutTask [id=58] check in Link [ id=24] CheckOutTask [id=57] check in Link [ id=23] CheckOutTask [id=54] check in Link [ id=27] CheckOutTask [id=52] check in Link [ id=11] CheckOutTask [id=38] check in Link [ id=9] CheckOutTask [id=39] check in Link [ id=12] CheckOutTask [id=56] check in Link [ id=26] CheckOutTask [id=41] check in Link [ id=8] CheckOutTask [id=53] check in Link [ id=19] CheckOutTask [id=55] check in Link [ id=13] CheckOutTask [id=48] check in Link [ id=28] CheckOutTask [id=49] check in Link [ id=29] CheckOutTask [id=51] check in Link [ id=20]
?
原文:http://zhangwei-david.iteye.com/blog/2224357