Java 是否必须关闭线程池?

Java 是否必须关闭线程池?,java,multithreading,executorservice,Java,Multithreading,Executorservice,我有一个web方法,它调用一个执行计算任务的方法。我使用了多线程方法,使用javaExecutorService调用此方法。以下是我目前的代码: @WebMethod public void performIntensiveCalculation() { ExecutorService pool = CalculationThreadPool.getInstance().getThreadPool(); pool.execute( calculate ); } 我的Calcul

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


保持线程池而不关闭是一种不好的做法吗?我是不是用错误的方式完成了任务?还有更好的办法吗

连接池应该在您的webapp生命周期内都可用,否则,使用它只会导致开销!这就是您的
CalculationThreadPool
使用单例模式的原因。
我认为您不需要手动关闭线程池,因为jvm将在关闭时杀死所有线程。无论如何,如果您仍然需要手动关闭,一个解决方案是添加一个
ServletContextListener
,并在其
contextdestromed
方法中执行。大概是这样的:

@WebListener
public class MyContextListener implements ServletContextListener {

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

请注意,关闭线程池有两种方法:
shutdown
shutdownNow
在处理当前运行的任务方面略有不同,您可以查看
ExecutorService
了解更多详细信息。

尽管当我们请求关闭JVM时JVM会杀死所有线程,最好显式关闭线程池,让任务正常停止。我们可以使用两阶段终止,关闭等待终止关闭现在。