【问题标题】:Is shutting down a thread pool mandatory?关闭线程池是强制性的吗?
【发布时间】:2019-11-24 05:31:28
【问题描述】:

我有一个调用方法执行计算任务的 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(),以后的请求将无法使用线程池。

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

【问题讨论】:

    标签: java multithreading executorservice


    【解决方案1】:

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

    @WebListener
    public class MyContextListener implements ServletContextListener {
    
        @Override
        public void contextDestroyed(ServletContextEvent e)
        {
            CalculationThreadPool.getInstance().getThreadPool().shutdownNow();
        }
    }
    

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

    【讨论】:

    • 虽然 JVM 在我们请求关闭 JVM 时会杀死所有线程,但最好明确关闭线程池以让任务优雅地停止。我们可以使用两阶段终止,shutdown-awaitTermination-shutdownNow。 javabyexamples.com/…
    猜你喜欢
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 2021-06-08
    • 2010-11-29
    • 2011-04-28
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    相关资源
    最近更新 更多