官方文档:
/** * Support class for throttling concurrent access to a specific resource. * * <p>Designed for use as a base class, with the subclass invoking * the {@link #beforeAccess()} and {@link #afterAccess()} methods at * appropriate points of its workflow. Note that {@code afterAccess} * should usually be called in a finally block! * * <p>The default concurrency limit of this support class is -1 * ("unbounded concurrency"). Subclasses may override this default; * check the javadoc of the concrete class that you're using. * * @author Juergen Hoeller * @since 1.2.5 * @see #setConcurrencyLimit * @see #beforeAccess() * @see #afterAccess() * @see org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor * @see java.io.Serializable */
beforeAccess()实现
/** * To be invoked before the main execution logic of concrete subclasses. * <p>This implementation applies the concurrency throttle. * @see #afterAccess() */ 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++; } } }
afterAccess()实现
/** * To be invoked after the main execution logic of concrete subclasses. * @see #beforeAccess() */ 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(); } } }
ConcurrencyThrottleSupport是个抽象类,其具体的实现类ConcurrencyThrottleInterceptor
/** * Interceptor that throttles concurrent access, blocking invocations * if a specified concurrency limit is reached. * * <p>Can be applied to methods of local services that involve heavy use * of system resources, in a scenario where it is more efficient to * throttle concurrency for a specific service rather than restricting * the entire thread pool (e.g. the web container's thread pool). * * <p>The default concurrency limit of this interceptor is 1. * Specify the "concurrencyLimit" bean property to change this value. * * @author Juergen Hoeller * @since 11.02.2004 * @see #setConcurrencyLimit */ @SuppressWarnings("serial") 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(); } } }
微信公众号: 架构师日常笔记 欢迎关注!