“一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。”
我们一般用它来控制某个对象的线程访问对象
例如,对于某个容器,我们规定,最多只能容纳n个线程同时操作
使用信号量来模拟实现
Test用例如下(目的是利用信号量来控制set集合中最多只包含三个元素,其中syn关键字只是为了能够直观的观测到结果添加的,如果不需要观测set集合的大小可以去掉提高性能):
package concurrentTest;
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 TestSemaphore {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
TestSemaphore t = new TestSemaphore();
final BoundedHashSet<String> set = t.getSet();
for (int i = 0; i < 20; i++) {//三个线程同时操作add
exec.execute(new Runnable() {
public void run() {
try {
set.add(Thread.currentThread().getName()
Thread.sleep(500);
set.remove(Thread.currentThread().getNam
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// for (int j = 0; j < 4; j++) {//三个线程同时操作remove
// exec.execute(new Runnable() {
// public void run() {
// set.remove(Thread.currentThread().getName(
// }
// });
// }
exec.shutdown();
}
public BoundedHashSet<String> getSet() {
return new BoundedHashSet<String>(3);//定义一个边界约束为2的线程
}
class BoundedHashSet<T> {
private final Set<T> set;
private final Semaphore semaphore;
public BoundedHashSet(int bound) {
this.set = Collections.synchronizedSet(new HashSet<T
this.semaphore = new Semaphore(bound, true);
}
public void add(T o) throws InterruptedException {
semaphore.acquire();//信号量控制可访问的线程数目
set.add(o);
synchronized (this) {
System.out.println(set.size());
}
System.out.printf("add:%s%n",o);
}
public synchronized void remove(T o) {
synchronized (this) {
if (set.remove(o))
semaphore.release();//释放掉信号量
}
System.out.printf("remove:%s%n",o);
}
}
} 输出如下:
1
2
add:pool-1-thread-2
add:pool-1-thread-1
3
add:pool-1-thread-3
remove:pool-1-thread-2
3
add:pool-1-thread-4
remove:pool-1-thread-3
remove:pool-1-thread-1
3
add:pool-1-thread-6
3
add:pool-1-thread-5
remove:pool-1-thread-5
3
add:pool-1-thread-7
remove:pool-1-thread-4
remove:pool-1-thread-6
3
add:pool-1-thread-9
3
add:pool-1-thread-8
remove:pool-1-thread-7
3
add:pool-1-thread-10
remove:pool-1-thread-8
remove:pool-1-thread-9
3
add:pool-1-thread-12
3
add:pool-1-thread-11
remove:pool-1-thread-10
3
add:pool-1-thread-13
remove:pool-1-thread-12
remove:pool-1-thread-11
3
add:pool-1-thread-15
3
add:pool-1-thread-14
remove:pool-1-thread-15
remove:pool-1-thread-14
3
add:pool-1-thread-16
remove:pool-1-thread-13
3
add:pool-1-thread-18
3
add:pool-1-thread-17
remove:pool-1-thread-18
3
add:pool-1-thread-19
remove:pool-1-thread-17
remove:pool-1-thread-16
2
add:pool-1-thread-20
remove:pool-1-thread-20
remove:pool-1-thread-19
825

被折叠的 条评论
为什么被折叠?



