Semaphore

2021/01/04 posted in  并发工具

用来控制同时访问特定资源的线程数量,它通过协调线程,合理的使用公共资源

信号量模型

信号量模型:一个等待队列,一个计数器,三个方法

  • init : 设置计数器的初始值
  • down : 计数器的值减一,如果此时计数器的值小于0,则当前线程被阻塞,否则当前线程可以继续执行
  • up : 计数器的值增一,如果此时计数器的值小于等于0,唤醒等待队列中的一个线程,并将线程删除

class Semaphore{
  // 计数器
  int count;
  // 等待队列
  Queue queue;
  // 初始化操作
  Semaphore(int c){
    this.count=c;
  }
  // 
  void down(){
    this.count--;
    if(this.count<0){
      //将当前线程插入等待队列
      //阻塞当前线程
    }
  }
  void up(){
    this.count++;
    if(this.count<=0) {
      //移除等待队列中的某个线程T
      //唤醒线程T
    }
  }
}

限流器 - 允许多个线程访问临界资源


class ObjPool<T, R> {
  final List<T> pool;
  // 用信号量实现限流器
  final Semaphore sem;
  // 构造函数
  ObjPool(int size, T t){
    pool = new Vector<T>(){};
    for(int i=0; i<size; i++){
      pool.add(t);
    }
    sem = new Semaphore(size);
  }
  // 利用对象池的对象,调用func
  R exec(Function<T,R> func) {
    T t = null;
    sem.acquire();
    try {
      t = pool.remove(0);
      return func.apply(t);
    } finally {
      pool.add(t);
      sem.release();
    }
  }
}
// 创建对象池
ObjPool<Long, String> pool = 
  new ObjPool<Long, String>(10, 2);
// 通过对象池获取t,之后执行  
pool.exec(t -> {
    System.out.println(t);
    return t.toString();
});