java - 我是否需要在实现 MessageListener 类的类的 onMessage 方法中关闭执行器?

标签 java spring

我有一个使用 Spring 框架的 Java 应用程序。它是一个监听器应用程序,可以非常快速地使用线程从某个源异步获取消息并将其保存到数据库中。

我正在使用 ExecutorService,它在 Servlet 类中初始化并存储在可以通过 onMessage() 方法访问的静态变量中。

我想知道的是,如果我总是收到消息,是否需要关闭 ExecutorService。如果我需要关闭执行器,我应该把它放在哪里?

@Override
public void onMessage(Message message) {
    String msg = "";
    ExecutorService taskExecutor;

    try {
        taskExecutor = StartupServlet.taskManager.getExecutor();
        msg = extractMessage(message);
        taskExecutor.execute(new MessageTask(msg));
        // Where do I place taskExecutor.shutdown();? Doing so here will reject the succeeding tasks, which breaks the listener.
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我正在使用 Spring Beans 来初始化线程,它工作正常。我只是不确定是否应该关闭它还是根本不关闭它。

<bean id="taskManager" class="com.company.threading.TaskManager">
    <property name="executor" ref="executorService"/>
</bean>

<bean id="executorService" 
      class="java.util.concurrent.Executors" 
      factory-method="newFixedThreadPool" 
      destroy-method="shutdown">
    <constructor-arg value="5"/>
</bean>

谢谢。

最佳答案

假设 com.company.threading.TaskManager 是您的自定义类,您不需要在 onMessage 内调用 shutdown,因为如果这样做您将无法处理其他消息。

您需要做的是在 Spring 上下文关闭时优雅地终止您的执行器

@Component
public class ContextClosedHandler implements ApplicationListener<ContextClosedEvent> {

    @Autowired
    @Qualifier("executorService")
    private ExecutorService executor;

    @Override
    public void onApplicationEvent(ContextClosedEvent event) {
        executor.shutdown();
        try {
            // define how much time to wait for the completion
            if (!executor.awaitTermination(15, TimeUnit.MINUTES)) { 
                List<Runnable> incompleteTask = executor.shutdownNow();
                // do that you want with them
            }
        } catch (InterruptedException e) {
            // handle or log exception
        }
    }
}

另外,我建议您不要使用静态对象来获取执行程序实例,例如 StartupServlet.taskManager.getExecutor()。让 Spring 为你做这件事!

@Autowired
@Qualifier("executorService")
private ExecutorService executor;

希望对你有帮助!

关于java - 我是否需要在实现 MessageListener 类的类的 onMessage 方法中关闭执行器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44323480/

相关文章:

java - 如何在java中使用neuroph创建一个简单的神经网络

java - 如何找到两个单链表的交集

BufferedImage 的 Java 抗锯齿

java - 未找到用户类型 (JPA) 的属性姓氏

java - Spring Boot 中的子 Controller

Spring Boot @Table 注解,不同环境的目录属性

java - 检查记录器级别的启用与不检查 SLF4J\Logback

java - 将文件读入字节数组,并使用填充进行 8 字节对齐 - Java

java - spring-boot: Autowiring 2 个变量但指向一个 bean

sql - 使用事务更新