Java - 自定义线程池与具有异步处理程序的 Spring 事件

Java - Custom Thread Pool vs Spring Event with Async Handlers

提问人:user762421 提问时间:7/7/2023 更新时间:7/7/2023 访问量:308

问:

我正在努力拦截服务层方法并捕获运行时业务数据并将其写入某种持久性。截获这些方法后,我计划异步执行持久性部分。我正在努力评估我是否应该使用 ExecutorService 或将 Spring Events 与 Async Handler 一起使用。

使用这两种方法的优缺点是什么?

Java Spring 事件 观察者模式

评论


答:

2赞 Peng 7/7/2023 #1

在自然界中,线程池和spring事件异步之间没有区别。从技术上讲,它们都位于 jdk 提供的包上,用于并发请求。但是它们的用法有不同的用法和场景。JUC

线程池

  • 线程池通常用于通用异步处理,在这种处理中,您希望将任务负载到单独的线程以进行并行执行。

以下是 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

  • Spring 事件提供了一种机制,用于 Spring 应用程序中组件之间的通信和解耦。
  • 你可以专注于你的业务,而不是环境

以下是 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;
    }
}

正如 pervious 确定的那样,基于 ,您可以将其重新关联为一个超集,以提供更集成和简化的方法。但是,如果您需要对线程执行和资源分配进行细粒度控制,或者如果您对事件处理之外的异步处理有更广泛的需求,线程池可能更合适。Spring EventThread pool