如何使用Spring正确关闭执行程序服务? [英] How to properly shutdown executor services with Spring?

查看:313
本文介绍了如何使用Spring正确关闭执行程序服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个命令行应用程序,它使用Spring管理的bean,它由java ExecutorService 组成:

I have a command line application that uses a Spring-managed bean that's composed of a java ExecutorService created with:

ExecutorService service = Executors.newFixedThreadPool(4);

现在,我希望我的服务在我的应用程序关闭时关闭,所以我让我的bean实现了 DisposableBean 接口并有一个destroy方法,例如:

Now, I want my service to shutdown when my application shuts down, so I made my bean implement the DisposableBean interface and have a destroy method such as:

public void destroy(){
  service.shutdown();
}

然后我可能想做一些事情,比如在Spring上注册一个关闭钩子上下文。然而,我发现(艰难的方式,即在预生产版本中)这不起作用:在 ExecutorService.shutdown()方法被调用,导致经典的catch 22问题(它会在中断时被调用,即,如果我在应用程序运行时按Ctrl-C)。这逃过了我的单元测试,因为出于某些原因它似乎在JUnit中工作正常,这仍然让我感到困惑:JUnit做了什么不同的事情?

Then I might be tempted to do something like register a shutdown hook on the Spring context. However I found out (the hard way, i.e., in a pre-production release) that this doesn't work: the shutdown hook doesn't get called before the ExecutorService.shutdown() method is called, causing a classic catch 22 problem (it does get called on interruption, i.e., if I hit Ctrl-C while the application is running). This escaped my unit tests because for some reason it seems to work fine from within JUnit, which is still puzzling me: what does JUnit do differently?

我找到的解决方案远在我退出main函数之前显式调用 ApplicationContext.close()。我想知道是否有更好的解决方案,以及拥有由Spring管理的灵活线程池的最佳实践。如果我的bean是直接由Spring管理但是由Spring管理的bean创建的呢?我应该将调用级联到 destroy()吗?这不是很容易出错吗?

The solution I found so far is to explicitly call ApplicationContext.close() right before I exit my main function. I was wondering if there was a better solution to this and what are the best practices for having flexible thread pools managed by Spring. Also what if my bean is not directly managed by Spring but is created by a bean managed by Spring? Should I just cascade the calls to destroy()? Wouldn't this be very error prone?

我感谢任何评论,建议,进一步阅读,RTFM,魔法食谱。

I appreciate any comments, suggestions, further reading, RTFMs, magic recipes.

谢谢!

推荐答案

你知道吗:

ExecutorService service = Executors.newFixedThreadPool(4);

可以替换为:

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

弹簧上下文然后更直接地管理执行器服务的关闭 - 它可以是更容易重复使用。

The spring context then manages, more directly, the shutdown of your executor service--and it can be more easily reused.

这篇关于如何使用Spring正确关闭执行程序服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆