如何在Spring Boot AsyncConfigurer中使用优先级队列

时间:2018-09-27 12:28:03

标签: java spring spring-boot asynchronous threadpoolexecutor

我有一个应用程序,其中有多个线程从jms目标读取消息。侦听器线程读取消息,对其进行一些更改,然后调用其他不同类的方法。这些方法带有@Async注释,所有方法都使用自定义ThreadPoolTaskExecutor并行执行。

@Override
public Executor getAsyncExecutor() {        
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(corePoolSize);
    executor.setMaxPoolSize(maxPoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.setTaskDecorator(new LoggingTaskDecorator());
    executor.initialize();
    return executor;
}

直到现在所有消息都被认为具有同等优先级,否则一切都很好,因为如果没有LinkedBlockingQueue线程可用,那么所有消息都将进入Executor

现在,存在一个要求,即从队列中读取的特定消息类型比从队列中读取的其他任何消息都具有更高的优先级。

当前,我使用的是“ org.springframework.scheduling.concurrent.ThreadPoolTask​​Executor”,它没有提供任何方法可以将Priority Queue设置为Blocking队列实现。

能否请您帮我解决这种情况? 还是系统的现有设计无法适应这种变化? 还是处理此类情况的最佳解决方案是什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

只需覆盖createQueue方法即可。另外,您还应该使用@Bean方法来创建bean的实例,这样Spring可以正确地管理生命周期,这是一件很小但是很重要的事情(否则关闭将无法正常工作)。

@Override
public Executor getAsyncExecutor() {
  return taskExecutor();
}        

@Bean    
public ThreadPoolTaskExecutor taskExecutor() {        
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor() {
    protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
      return new PriorityBlockingQueue<>(queueCapacity);
    } 
  };
  executor.setCorePoolSize(corePoolSize);
  executor.setMaxPoolSize(maxPoolSize);
  executor.setQueueCapacity(queueCapacity);
  executor.setKeepAliveSeconds(keepAliveSeconds);
  executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  executor.setTaskDecorator(new LoggingTaskDecorator());  
  return executor;
}

类似的事情应该起作用。现在,createQueue方法将创建一个PriorityBlockingQueue而不是默认的LinkedBlockingQueue