Java 在多用户JSP J2EE应用程序中创建和关闭ExecutorService实例

Java 在多用户JSP J2EE应用程序中创建和关闭ExecutorService实例,java,jsp,threadpool,executorservice,java.util.concurrent,Java,Jsp,Threadpool,Executorservice,Java.util.concurrent,我们有一个基于多用户令牌的JSP应用程序。 我们在一个专用的类中管理所有会话SessionManager。 后者在新用户打开任何应用程序页面(通常是主页)时初始化会话并将其缓存在映射中,并在关联令牌不再有效时销毁此会话。因此,我们有SessionManager::init和SessionManager::destroy 最近,我在我们的应用程序中引入了ExecutorService,用于一些通过AJAX调用从前端开始的异步任务和一些耗时的方法 我在SessionManager::init中创建并

我们有一个基于多用户令牌的JSP应用程序。 我们在一个专用的类中管理所有会话
SessionManager
。 后者在新用户打开任何应用程序页面(通常是主页)时初始化会话并将其缓存在映射中,并在关联令牌不再有效时销毁此会话。因此,我们有
SessionManager::init
SessionManager::destroy

最近,我在我们的应用程序中引入了
ExecutorService
,用于一些通过AJAX调用从前端开始的异步任务和一些耗时的方法

我在
SessionManager::init
中创建并将
ExecutorService
实例设置为session属性,并在
SessionManager::destroy
中关闭该实例(根据Oracle的建议)。通过这种方式,每个用户都有单独的
ExecutorService
实例,该实例由其会话令牌标识,只要用户使用该应用程序,该实例就一直存在

我对这种体系结构很满意,但将
ExecutorService
实例作为属性放在会话中并不是100%好

另一种方法是创建并公开
ExecutorService
实例以供所有用户会话使用。可能实现为线程安全的单例类但是如果我使用这种方法,我不知道在哪里关闭
ExecutorService
实例,我应该关闭吗


这是主要问题;是否可以继续使用当前实现:
ExecutorService
instance per user作为属性存储在当前会话中

为每个用户提供一个线程池看起来毫无意义,为什么

您需要使用
ServletContextListener
,一旦servlet上下文被创建和销毁(可能是应用程序范围),服务器就会调用它

比如说

@WebListener("daemon_dude")
public class daemon_dude implements ServletContextListener{
...
private ScheduledExecutorService scheduler;//or whatever type of pool
public void contextInitialized(ServletContextEvent event) {
  scheduler = Executors.newSingleThreadScheduledExecutor();//and use it
}
public void contextDestroyed(ServletContextEvent event){
  scheduler.shutdownNow();//or any more peaceful approach
}
...
}

为每个用户提供一个线程池看起来毫无意义,为什么

您需要使用
ServletContextListener
,一旦servlet上下文被创建和销毁(可能是应用程序范围),服务器就会调用它

比如说

@WebListener("daemon_dude")
public class daemon_dude implements ServletContextListener{
...
private ScheduledExecutorService scheduler;//or whatever type of pool
public void contextInitialized(ServletContextEvent event) {
  scheduler = Executors.newSingleThreadScheduledExecutor();//and use it
}
public void contextDestroyed(ServletContextEvent event){
  scheduler.shutdownNow();//or any more peaceful approach
}
...
}