您的位置:首页 > 编程语言 > Java开发

《java并发编程实战》基础构建模块(六)

2014-11-15 10:03 218 查看
5.5.3 信号量

计数信号量用来控制同时访问某个资源的操作数量,或者同时执行某个指定操作的数量。另外还可以用来实现某种资源池,或者对容器施加边界。

例如:

package com.imeiren.cache;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class BoundedHashSet<T> {
private final Set<T> set;
private final Semaphore sem;

public BoundedHashSet(int bound) {
this.set = Collections.synchronizedSet(new HashSet<T>());
sem = new Semaphore(bound);
}

public boolean remove(Object o) {
boolean wasRemoved = set.remove(o);
if (wasRemoved) {
sem.release();
}
return wasRemoved;
}

public boolean add(T o) throws InterruptedException {
SimpleDateFormat formater = new SimpleDateFormat("hh:MM:ss");
System.out.println(formater.format(Calendar.getInstance().getTime())
+ " " + Thread.currentThread() + " enter add method");
sem.acquire();
System.out.println(formater.format(Calendar.getInstance().getTime())
+ " " + Thread.currentThread() + " finished waiting status");
boolean wasAdded = false;
try {
Thread.sleep(2000);
wasAdded = set.add(o);
return wasAdded;
} finally {
if (!wasAdded) {
sem.release();
}
}
}

public static void main(String[] args) {
final BoundedHashSet<String> set = new BoundedHashSet<String>(2);

ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executorService.execute(new Runnable() {

@Override
public void run() {
try {
set.add("Hello World!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}

executorService.shutdown();
}
}
某次执行的输出结果:
09:11:13 Thread[pool-1-thread-3,5,main] enter add method
09:11:13 Thread[pool-1-thread-5,5,main] enter add method
09:11:13 Thread[pool-1-thread-3,5,main] finished waiting status
09:11:13 Thread[pool-1-thread-1,5,main] enter add method
09:11:13 Thread[pool-1-thread-4,5,main] enter add method
09:11:13 Thread[pool-1-thread-2,5,main] enter add method
09:11:13 Thread[pool-1-thread-5,5,main] finished waiting status
09:11:15 Thread[pool-1-thread-1,5,main] finished waiting status
09:11:17 Thread[pool-1-thread-4,5,main] finished waiting status
09:11:19 Thread[pool-1-thread-2,5,main] finished waiting status
我们设置容器边界为2,用5个线程同时访问容器。我们看到在13秒时5个线程同时进入add方法,线程3、5不需要等待,在13秒时就结束等待状态,而之后其他三个线程分别在15、17、19秒的时候结束等待状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: