模拟一个停车场系统 设置有 5个车位 停满之后只有开走才能继续停发
在这里停车场是不知道自己有 几个车位的 我们是用信号量初始化来设置的 5 意思最多停满5个
如果还有人停车 就释放一个许可.
package com.lovo;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;
class CyclicBarrierWorker implements Runnable{
private Set<String> sets; //车库
private final Semaphore se; //门卫
CyclicBarrierWorker(int i) {
this.sets = Collections.synchronizedSet(new HashSet<String>()); //将 设置设置为同步容器
se = new Semaphore(i);
}
//车辆停车
public boolean add(String t) throws InterruptedException {
se.acquire(); //给出车位
System.out.println("获取一个许可");
boolean was = false;
try{
was = sets.add(t);//停车
long duration = (long)(Math.random()*10);
Thread.sleep(1000);
return was;
}finally {
if(!was){
se.release();
sets.remove(t);//一辆车开走
System.out.println("释放一个许可");
}
}
}
@Override
public void run() {
try {
add("车辆");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestCyclicBarrier {
public static void main(String[] args) {
CyclicBarrierWorker c =new CyclicBarrierWorker(5);
//模拟10辆车 进行停放
for(int i = 0 ;i<10;i++){
new Thread(c).start();
}
}
}
结果:
获取一个许可
获取一个许可
获取一个许可
获取一个许可
获取一个许可
获取一个许可
释放一个许可
释放一个许可
获取一个许可
释放一个许可
获取一个许可
获取一个许可
释放一个许可
释放一个许可
获取一个许可
释放一个许可
信号量Semapphore 管理者一组虚拟的许可 许可在构造函数中进行初始化并在使用完许可后进行释放
如果执行线程没有许可 就会进行阻塞直到获取到许可(或则直到被中断 执行超时) release方法可以返回也就是释放一个许可信号量 acquire方法可以获取到一个许可 当我们设置的许可 上面设置的是5个 获取完了 那么就会进行 释放 并让其他线程 获取到释放的一个许可 谁拥有了这个许可就相当拥有了 互斥锁。
可以实现 数据库连接池 线程池等功能