在库中管理ExecutorService的最佳实践是什么?



在我的一个库中,我使用了一个有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的附加要求提供者。

  1. 所有任务,当从ManagedExecutorService执行时,将使用提交的组件的Java EE组件标识运行这个任务。
  2. ManagedExecutorService的生命周期由应用服务器管理。的所有生命周期操作ManagedExecutorService接口将抛出java.lang.IllegalStateException例外。这包括类中定义的以下方法java.util.concurrent.ExecutorService接口:awaitTermination();isShutdown(), isTerminated(), shutdown()和shutdownNow()。最后释放3-11
  3. 如果任务的组件未启动,则提交给执行器的任务不能运行。

当ManagedExecutorService实例被关闭时Java EE产品提供者:

  1. 所有尝试提交新任务被拒绝。
  2. 所有提交的任务如果没有运行将被取消。
  3. 所有正在运行的任务线程被中断。
  4. 所有已注册的managedtasklistener被调用

相关内容

最新更新