关闭线程池是强制性的吗?

Is shutting down a thread pool mandatory?

我有一个调用方法执行计算任务的 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方法,请求可以随时来进行计算。我无法理解的是如何在创建的池中调用关闭方法。如果我在 pool.execute() 行之后调用 pool.shutdown(),以后的请求将无法使用线程池。

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

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

@WebListener
public class MyContextListener implements ServletContextListener {

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

请注意,有两种关闭线程池的方法:shutdownshutdownNow 这两种方法在处理当前 运行 任务方面略有不同,您可以采取查看 ExecutorService documentation 了解更多详情。