I am trying to use BlockingQueue inside Spring Boot. My design was like this: user submit request via a controller and controller in turn puts some objects onto a blocking queue. After that the consumer should be able to take the objects and process further.
I have used Asnyc, ThreadPool and EventListener. However with my code below I found consumer class is not consuming objects. Could you please help point out how to improve?
Queue Configuration
@Bean public BlockingQueue<MyObject> myQueue() { return new PriorityBlockingQueue<>(); } @Bean public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(3); executor.setMaxPoolSize(3); executor.setQueueCapacity(10); executor.setThreadNamePrefix("Test-"); executor.initialize(); return executor; }
Rest Controller
@Autowired BlockingQueue<MyObject> myQueue; @RequestMapping(path = "/api/produce") public void produce() { /* Do something */ MyObject myObject = new MyObject(); myQueue.put(myObject); }
Consumer Class
@Autowired private BlockingQueue<MyObject> myQueue; @EventListener public void onApplicationEvent(ContextRefreshedEvent event) { consume(); } @Async public void consume() { while (true) { try { MyObject myObject = myQueue.take(); } catch (Exception e) { } } }
Advertisement
Answer
In the end I came up with this solution.
Rest Controller
@Autowired BlockingQueue<MyObject> myQueue; @RequestMapping(path = "/api/produce") public void produce() { /* Do something */ MyObject myObject = new MyObject(); myQueue.put(myObject); Consumer.consume(); }
It is a little bit weird because you have to first put the object on queue yourself then consume that object by yourself. Any suggestions on improvement is highly appreciated.