在我的一个库中,我使用了一个有5个线程的固定线程池执行器;我的线程不是重量级的,我.get()
有超时,但对于ExecutorService
,我创建它,之后,这是"生而让死"。
当你用完它时,你应该给它.shutdown{,Now}()
;但这是一个库,我不能提前知道它将如何使用:与一个简单的main()
,在一个将由servlet容器管理的web应用程序,其他。
这感觉不对。我怎样才能做得更好?我应该使用ExecutorService
以外的东西吗?
EDIT链接到唯一的用户:here;守护线程可能是一种解决方案,现在我不知道它们是否有缺点,我应该意识到…
好吧,这不是一个真正的答案,更像是一个想法…
正如我在之前的评论中已经提到的,您的LoadingMessageSourceProvider
组件保持状态,因此必须有人负责正确关闭组件。您可以尝试通过注册一个关闭钩子(我在这里不考虑finalize
:-)将其作为组件的一部分来实现。
我宁愿把它留给组件的用户(应用程序),因为它更好地知道何时关闭。事实上,你正在实现一个具有生命周期的轻量级容器——在某种程度上类似于Java EE 7容器提供程序实现JSR-236。
如果没有可用的JSR-236容器,则必须启用调用者来管理生命周期。我可以想到一个工厂方法,简单的例子:
// maintains the executor service (one service per factory)
private MessageSourceProviderFactory f = MessageSourceProviderFactory.instance();
private void stuff() {
MessageSourceProvider msp = f.newBuilder()/*. [...] */.build();
// work with the provider
}
// at some point in time the caller decides to finish
private void end() {
f.shutdown(); // shutdown the factory and the ExecutorService
}
JSR-236第3.1.6.1节在生命周期方面相当有趣:
3.1.6.1 Java EE产品提供商要求介绍ManagedExecutorService的附加要求提供者。
- 所有任务,当从ManagedExecutorService执行时,将使用提交的组件的Java EE组件标识运行这个任务。
- ManagedExecutorService的生命周期由应用服务器管理。的所有生命周期操作ManagedExecutorService接口将抛出java.lang.IllegalStateException例外。这包括类中定义的以下方法java.util.concurrent.ExecutorService接口:awaitTermination();isShutdown(), isTerminated(), shutdown()和shutdownNow()。最后释放3-11
- 如果任务的组件未启动,则提交给执行器的任务不能运行。
当ManagedExecutorService实例被关闭时Java EE产品提供者:
- 所有尝试提交新任务被拒绝。
- 所有提交的任务如果没有运行将被取消。
- 所有正在运行的任务线程被中断。
- 所有已注册的managedtasklistener被调用