是否必须关闭线程池?

时间:2019-11-24 05:31:28

标签: java multithreading executorservice

我有一个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(),将来的请求将无法使用线程池。

在不关闭线程池的情况下保留线程池是一种不好的做法吗?我使用错误的方式完成任务吗?有什么更好的办法吗?

1 个答案:

答案 0 :(得分:1)

连接池在您的Web应用程序的整个生命周期内都应该可用,否则,使用它只会造成开销!这就是为什么您的CalculationThreadPool使用单例模式的原因。 我认为您不需要手动关闭线程池,因为jvm会在关闭时杀死所有线程。无论如何,如果仍然需要手动关闭,一种解决方案是添加一个ServletContextListener并使用其contextDestroyed方法。像这样:

@WebListener
public class MyContextListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent e)
    {
        CalculationThreadPool.getInstance().getThreadPool().shutdownNow();
    }
}

请注意,有两种关闭线程池的方法:shutdownshutdownNow在应付当前正在运行的任务方面略有不同,您可以看看{{1 }} documentation