JUC共享锁之Semaphore
Semaphore原意是指信号量,从API的注释:”Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource”可以看出,Semaphore一般是用来限制线程能够使用的资源个数.
应用场景
在Web开发中,Semaphore可以用来限制某个接口的并发调用次数.可以在Sping的Context中维护一个Map,key可以是处理线程,value可以是一个Semaphore对象.通过这样的方式,就可以实现系统同时处理的线程数不会超过某个阈值.
代码实现
我们可以通过WebFilter注解,来实现一个过滤器,在过滤器中拦截所有的请求调用,然后通过Semaphore来进行计数,如果超过总的计数,则返回相应的提示信息.当然也可以对URL进行细化,针对每个API提供对应的限制.
/**
* API并发控制过滤器
* Created by qiaohe
* Date: 19-7-1 上午11:54
*/
@Component
@WebFilter(urlPatterns = "/*", filterName = "concurrentRestrictFilter")
public class ConcurrentRestrictFilter implements Filter {
private Log log = LogFactory.getLog(getClass());
private static final Integer MAX_CONCURRENT_NUM = 1;
private static final Semaphore semaphore = new Semaphore(MAX_CONCURRENT_NUM);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
log.info("before acquire: " + semaphore.availablePermits());
if(!semaphore.tryAcquire()){
if(response instanceof HttpServletResponse){
HttpServletResponse res = (HttpServletResponse)response;
res.setContentType(MimeTypeUtils.APPLICATION_JSON_VALUE);
res.sendError(HttpStatus.BAD_REQUEST.value(), "reach max current num");
}
return;
}
log.info("after acquire: " + semaphore.availablePermits());
try{
chain.doFilter(request, response);
} finally {
semaphore.release();
log.info("release: " + semaphore.availablePermits());
}
}
@Override
public void destroy() {
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!