我有一个Web方法,该方法调用一个方法来执行计算任务。我使用了一种多线程方法来使用java ExecutorService调用此方法。到目前为止,这是我的代码。
@WebMethod
public void performIntensiveCalculation()
{
ExecutorService pool = CalculationThreadPool.getInstance().getThreadPool();
pool.execute( calculate );
}
我的CalculationThreadPool实现如下,
public class CalculationThreadPool
{
private static CalculationThreadPool instance;
private ExecutorService pool;
private CalculationThreadPool()
{
pool = Executors.newFixedThreadPool( 3 );
}
public synchronized static CalculationThreadPool getInstance()
{
if( instance == null )
{
instance = new CalculationThreadPool();
}
return instance;
}
public ExecutorService getThreadPool()
{
return pool;
}
}
由于此方法作为Web方法公开,因此可以随时请求进行计算。因此,我不明白的是,如何在创建的池中调用shutdown方法。如果我在pool.execute()行之后立即调用pool.shutdown(),将来的请求将无法使用线程池。
在不关闭线程池的情况下保留线程池是一种不好的做法,还是我使用某种错误的方法来完成任务,还有更好的方法吗?
连接池应该在您的Web应用程序的整个生命周期中都可用,否则,使用它只会造成开销!这就是为什么您的CalculationThreadPool
使用单例模式。我认为您不需要手动关闭线程池,因为jvm会在关闭时杀死所有线程。无论如何,如果仍然需要手动关闭,一种解决方案是添加ServletContextListener
并以其contextDestroyed
方法执行。像这样的东西:
@WebListener
public class MyContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent e)
{
CalculationThreadPool.getInstance().getThreadPool().shutdownNow();
}
}
[请注意,有两种关闭线程池的方法:shutdown
和shutdownNow
在应付当前正在运行的任务方面略有不同,有关更多信息,请参见ExecutorService
documentation。详细信息。