我有一个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.shutdown()
行之后调用pool.execute()
,将来的请求将无法使用线程池。
在不关闭线程池的情况下保留线程池是一种不好的做法吗?我使用错误的方式完成任务吗?有什么更好的办法吗?
答案 0 :(得分:1)
连接池在您的Web应用程序的整个生命周期内都应该可用,否则,使用它只会造成开销!这就是为什么您的CalculationThreadPool
使用单例模式的原因。
我认为您不需要手动关闭线程池,因为jvm会在关闭时杀死所有线程。无论如何,如果仍然需要手动关闭,一种解决方案是添加一个ServletContextListener
并使用其contextDestroyed
方法。像这样:
@WebListener
public class MyContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent e)
{
CalculationThreadPool.getInstance().getThreadPool().shutdownNow();
}
}
请注意,有两种关闭线程池的方法:shutdown
和shutdownNow
在应付当前正在运行的任务方面略有不同,您可以看看{{1 }} documentation。