java中提供的信号量实现Semaphore类
- 初始化10个信号量
Semaphore sem = new Semaphore(10);
- 获取信号量
sem.acquire(2);
- 入门级案例
private static final Integer SEM_MAX = 1;
public static void main(String[] args) {
Semaphore sem = new Semaphore(SEM_MAX);
ExecutorService threadPool = Executors.newFixedThreadPool(5);
//在线程池中执行任务
threadPool.execute(new MyThread(sem, 1));
threadPool.execute(new MyThread(sem, 1));
// threadPool.execute(new MyThread(sem, 7));
//关闭池
threadPool.shutdown();
}
}
class MyThread extends Thread {
private volatile Semaphore sem; // 信号量
private int count; // 申请信号量的大小
MyThread(Semaphore sem, int count) {
this.sem = sem;
this.count = count;
}
public void run() {
try {
// 从信号量中获取count个许可
sem.acquire(count);
System.out.println(Thread.currentThread().getName() + " start dosomething");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " end dosomething");
//System.out.println(" availble="+sem.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 释放给定数目的许可,将其返回到信号量。
sem.release(count);
System.out.println(Thread.currentThread().getName() + " release " + count + "");
}
}}
其中初始化信号量的值为1,则相当于锁的作用,每次只允许一个线程进入。
通过有上限的 Semaphore 可以限制进入某代码块的线程数量;
C语言中信号量的实现
- sem_id=semget(key,1,IPC_CREAT|0600);//创建信号量集
- semctl(sem_id,nsem_id,SETVAL,val) //初始化信号量
- semop(sem_id,&sbuf,1)//申请信号量
- semop(sem_id,&sbuf,1)//释放信号量
具体demo还在学习中
spring Zuul RateLimiter 限流
zuul网关限流——使用ZuulFilter和RateLimiter可以实现令牌桶限流,与信号量的思想差不多
//每秒产生1000个令牌,类似于Semaphore信号量中new Semaphore(1000);
private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);
@Override
public Object run() throws ZuulException {
//就相当于每调用一次tryAcquire()方法,令牌数量减1,当1000个用完后,那么后面进来的用户无法访问上面接
//当然这里只写类上面一个接口,可以这么写,实际可以在这里要加一层接口判断。
if (!RATE_LIMITER.tryAcquire()) {//类似于Semaphore信号量中acquire()方法
requestContext.setSendZuulResponse(false);
}
return null;
}