位置:org.springframework.util
�实现接口:java.io.Serializable
继承类:无
作用:辅助工具类,用于提供限制对特定资源的并发访问的API

一、效果

image.png
可以通过继承ConcurrencyTrhottleSupport的方式实现拦截器,比如ConcurrencyThrottleInterceptor。
拦截器中的invoke()方法中,在执行目标方法的前后分别执行beforeAccess()和 afterAccess()方法。

  1. public class ConcurrencyThrottleInterceptor extends ConcurrencyThrottleSupport
  2. implements MethodInterceptor, Serializable {
  3. public ConcurrencyThrottleInterceptor() {
  4. setConcurrencyLimit(1);
  5. }
  6. @Override
  7. public Object invoke(MethodInvocation methodInvocation) throws Throwable {
  8. beforeAccess();
  9. try {
  10. return methodInvocation.proceed();
  11. }
  12. finally {
  13. afterAccess();
  14. }
  15. }
  16. }

二、API

  1. /*
  2. 在beforeAccess方法中通过内部计数器concurrencyCount来对比设置的阀值concurrencyLimit,如果
  3. 超过设置值,则阻塞。若没有超过设置值,则concurrencyCount自加。
  4. */
  5. protected void beforeAccess() {
  6. if (this.concurrencyLimit == NO_CONCURRENCY) {
  7. throw new IllegalStateException(
  8. "Currently no invocations allowed - concurrency limit set to NO_CONCURRENCY");
  9. }
  10. if (this.concurrencyLimit > 0) {
  11. boolean debug = logger.isDebugEnabled();
  12. synchronized (this.monitor) {
  13. boolean interrupted = false;
  14. while (this.concurrencyCount >= this.concurrencyLimit) {
  15. if (interrupted) {
  16. throw new IllegalStateException("Thread was interrupted while waiting for invocation access, " +
  17. "but concurrency limit still does not allow for entering");
  18. }
  19. if (debug) {
  20. logger.debug("Concurrency count " + this.concurrencyCount +
  21. " has reached limit " + this.concurrencyLimit + " - blocking");
  22. }
  23. try {
  24. this.monitor.wait();
  25. }
  26. catch (InterruptedException ex) {
  27. // Re-interrupt current thread, to allow other threads to react.
  28. Thread.currentThread().interrupt();
  29. interrupted = true;
  30. }
  31. }
  32. if (debug) {
  33. logger.debug("Entering throttle at concurrency count " + this.concurrencyCount);
  34. }
  35. this.concurrencyCount++;
  36. }
  37. }
  38. }
  39. // 在afterAccess方法中自减concurrencyCount,随后释放阻塞的资源。
  40. protected void afterAccess() {
  41. if (this.concurrencyLimit >= 0) {
  42. synchronized (this.monitor) {
  43. this.concurrencyCount--;
  44. if (logger.isDebugEnabled()) {
  45. logger.debug("Returning from throttle at concurrency count " + this.concurrencyCount);
  46. }
  47. this.monitor.notify();
  48. }
  49. }
  50. }

三、总结

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

四、补充


参考资料: spring控制并发数的工具类ConcurrencyThrottleSupport和ConcurrencyThrottleInterceptor