码迷,mamicode.com
首页 > 编程语言 > 详细

spring控制并发数的工具类ConcurrencyThrottleSupport和ConcurrencyThrottleInterceptor

时间:2018-08-07 13:16:35      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:rom   invoke   catch   simple   exec   odi   spring   deb   控制   

在ConcurrencyThrottleSupport类中,简单的通过synchronized和wati and notify达到控制线程数量的效果,从而实现限流的策略。

一、类图

技术分享图片

二、主要方法

技术分享图片

先看ConcurrencyThrottleInterceptor.java类的源码:

看该拦截器中的invoke()方法中,在执行目标方法的前后分别执行beforeAccess()和 afterAccess()方法,

  • beforeAccess方法中通过内部计数器concurrencyCount来对比设置的阀值concurrencyLimit,如果超过设置值,则阻塞。若没有超过设置值,则concurrencyCount自加。
  • afterAccess方法中自减concurrencyCount
public class ConcurrencyThrottleInterceptor extends ConcurrencyThrottleSupport
        implements MethodInterceptor, Serializable {

    public ConcurrencyThrottleInterceptor() {
        setConcurrencyLimit(1);
    }

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        beforeAccess();
        try {
            return methodInvocation.proceed();
        }
        finally {
            afterAccess();
        }
    }

}

 

beforeAccess()实现(在父类ConcurrencyThrottleSupport中实现)

    protected void beforeAccess() {
        if (this.concurrencyLimit == NO_CONCURRENCY) {
            throw new IllegalStateException(
                    "Currently no invocations allowed - concurrency limit set to NO_CONCURRENCY");
        }
        if (this.concurrencyLimit > 0) {
            boolean debug = logger.isDebugEnabled();
            synchronized (this.monitor) {
                boolean interrupted = false;
                while (this.concurrencyCount >= this.concurrencyLimit) {
                    if (interrupted) {
                        throw new IllegalStateException("Thread was interrupted while waiting for invocation access, " +
                                "but concurrency limit still does not allow for entering");
                    }
                    if (debug) {
                        logger.debug("Concurrency count " + this.concurrencyCount +
                                " has reached limit " + this.concurrencyLimit + " - blocking");
                    }
                    try {
                        this.monitor.wait();
                    }
                    catch (InterruptedException ex) {
                        // Re-interrupt current thread, to allow other threads to react.
                        Thread.currentThread().interrupt();
                        interrupted = true;
                    }
                }
                if (debug) {
                    logger.debug("Entering throttle at concurrency count " + this.concurrencyCount);
                }
                this.concurrencyCount++;
            }
        }
    }

 beforeAccess()实现(在父类ConcurrencyThrottleSupport中实现)

    protected void afterAccess() {
        if (this.concurrencyLimit >= 0) {
            synchronized (this.monitor) {
                this.concurrencyCount--;
                if (logger.isDebugEnabled()) {
                    logger.debug("Returning from throttle at concurrency count " + this.concurrencyCount);
                }
                this.monitor.notify();
            }
        }
    }

 使用场景见《spring异步线程池-SimpleAsyncTaskExecutor

spring控制并发数的工具类ConcurrencyThrottleSupport和ConcurrencyThrottleInterceptor

标签:rom   invoke   catch   simple   exec   odi   spring   deb   控制   

原文地址:https://www.cnblogs.com/duanxz/p/9435873.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!