Java 我是否需要关闭实现MessageListener类的类的onMessage方法的执行器?

Java 我是否需要关闭实现MessageListener类的类的onMessage方法的执行器?,java,spring,Java,Spring,我有一个使用Spring框架的Java应用程序。它是一个侦听器应用程序,可以使用线程非常快速地从某个源异步获取消息,并将其保存到数据库中 我正在使用ExecutorService,它在一个Servlet类中初始化,并存储在一个静态变量中,可以通过onMessage()方法访问该静态变量 我想知道的是,如果我总是收到消息,是否需要关闭Executor服务。如果我需要关闭执行器,我应该把它放在哪里 @Override public void onMessage(Message message) {

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

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

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

@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();
    }
}
我正在使用Springbean初始化线程,它工作得很好。我只是不确定是否应该关闭它

<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上下文关闭时优雅地终止executor

@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
        }
    }
}

希望有帮助

您好,很抱歉延迟回复。这看起来确实很有帮助,但我确实对如何实现这一点有疑问。如何在此处包含包含执行器服务的xml文件?另外,我的
TaskManager
类只是
执行器的一个简单的getter和setter。我应该把这个放在哪里?我是否必须显式关闭()ApplicationContext才能激活此事件?如果是这样,如果不是在onMessage事件中,我应该在哪里做呢?@Wax,如果您使用标准的maven目录布局,xml文件应该在src/main/resources目录中。我建议不要使用TaskManager,而只注入executorService bean,如答案所示。您不需要显式地调用close方法,在这里您只需注册侦听器,Spring将自己调用它。
executorService
在尝试
@Autowired
版本时总是
null
。为什么呢?我试着在谷歌上搜索一下,但到目前为止都没有成功,我几乎没有什么想法。当使用我使用的静态变量时,它工作得很好。我通过
标记将bean xml包含到web.xml中,并且正在检测它。@Wax,如果自动连线不起作用,这意味着您的配置有问题。我现在设法使它起作用了。事实证明,我需要将其包含在xml中<代码>
谢谢你,伙计!
@Autowired
@Qualifier("executorService")
private ExecutorService executor;