How to use blocking queue in Spring Boot?

Tags: , ,



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) {
        }
    }
}

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.



Source: stackoverflow