Search code examples
javaspringeventsobserver-pattern

Java - Custom Thread Pool vs Spring Event with Async Handlers


I am working on intercepting service layer methods and capture runtime business data and write it to some sort of persistence. After intercepting the methods, I am planning to do the persistence part asynchronously. I am working on evaluating if I should use ExecutorService or use Spring Events with Async Handler.

What could be the pros and cons of using either of the approach?


Solution

  • In nature , There is no difference between thread pool and spring event async. Technically , both of them lies on JUC package which is provied by jdk used to concurrently request. But the usage of them has different usage and scenario.

    Thread pool

    • Thread pooling is typically used for general-purpose asynchronous processing, where you want to payload tasks to separate threads for parallel execution.

    following is sample code snippet of Thread pool

    ExecutorService executorService = Executors.newFixedThreadPool(5);
    
            for (int i = 0; i < 10; i++) {
                final int taskId = i;
                executorService.execute(() -> {
                    // Perform asynchronous task
                    System.out.println("Executing task: " + taskId);
                });
            }
    

    Spring Events with Async Handlers

    • Spring events provide a mechanism for communication and decoupling between components within a Spring application.
    • you can focus on your bussiness , not environment

    following is sample code snippet of Spring Events

    @Configuration
    @EnableAsync
    public class SpringEventsThreadPoolExample {
    
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringEventsThreadPoolExample.class);
            
            // Publish an event
            MyEvent event = new MyEvent("Hello, Spring Events with Custom Thread Pool!");
            context.publishEvent(event);
        }
    
        public static class MyEvent {
            private String message;
    
            public MyEvent(String message) {
                this.message = message;
            }
    
            public String getMessage() {
                return message;
            }
        }
    
        @Async
        @EventListener
        public void handleEvent(MyEvent event) {
            // Perform asynchronous event handling
            System.out.println("Handling event: " + event.getMessage() + " on thread: " + Thread.currentThread().getName());
        }
    
        @Bean
        public ThreadPoolTaskExecutor taskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(10);
            executor.setMaxPoolSize(20);
            executor.setQueueCapacity(50);
            executor.setThreadNamePrefix("async-thread-");
            executor.initialize();
            return executor;
        }
    }
    

    As pervious determine, Spring Event is based on Thread pool , you can relaize it as a superset that provide more integrated and streamlined approach. howeveer,if you need fine-grained control over thread execution and resource allocation, or if you have a broader need for asynchronous processing beyond event handling, thread pooling might be more appropriate.