Semaphore信号量java
在管程被提出来以前用的是信号量。服务器
一个计数器,一个等待队列,三个方法。计数器和等待队列对外是透明的,因此只能经过信号量模型提供的三个方法来访问他们,这三个方法分别是:init()、down()、up()并发
这三个方法都是原子性的,原子性是由信号量模型的实现方保证的。在Java SDK里面,信号量模型是由java.util.concurrent.Semaphore实现的,Semaphore这个类可以保证这 三个方法都是原子操做。app
import java.util.Queue; /** * 信号量 **/ public class Semaphore { //计数器 int count; //等待队列 Queue<String> queue; //初始化操做 Semaphore(int count){ this.count = count; } void down(){ this.count--; if (this.count<0){ //将当前线程插入等待队列 //阻塞当前线程 } } void up(){ this.count ++ ; if (this.count>=0){ //移出等待队列中的某个线程T //唤醒线程T } } }
在JavaSDK并发包里,down()和up()对应的则是acquire()和release()。ui
实现一个限流器:this
import java.util.List; import java.util.Vector; import java.util.concurrent.Semaphore; import java.util.function.Function; /** * * **/ public class ObjPool<T,R> { //对象池 final List<T> pool; //信号量 final Semaphore sem; /** * 向线程池里添加数据 * @param size 对象数量 * @param t */ public ObjPool(int size, T t) { this.pool = new Vector<>(); for (int i=0; i<size;i++){ pool.add(t); } sem = new Semaphore(size); } R exec(Function<T,R> func) throws Exception{ T t = null; sem.acquire();//计数器 -1 try { t = pool.remove(0);//从队列中去除一个值 return func.apply(t); }finally { pool.add(t); sem.release();//计数器+1 } } public static void main(String[] args) throws Exception{ ObjPool<Long, String> pool = new ObjPool<>(10, 2L); pool.exec(t -> { System.out.println(t); return t.toString(); }); } }
**** 码字不易若是对你有帮助请给个关注****线程
**** 爱技术爱生活 QQ群: 894109590****code