【问题标题】:Java Executor and Long-lived ThreadsJava 执行器和长寿命线程
【发布时间】:2013-10-22 09:32:59
【问题描述】:

我继承了一些使用 Executors.newFixedThreadPool(4); 的代码运行 4 个长期存在的线程来完成应用程序的所有工作。

这是推荐的吗?我读过Java Concurrency in Practice 这本书,似乎没有太多关于如何管理长期应用程序线程的指导。

在应用程序的整个生命周期中启动和管理多个线程的推荐方法是什么?

【问题讨论】:

    标签: java multithreading concurrency executorservice


    【解决方案1】:

    你提到代码使用Executors,它应该返回一个ExecutorService

    ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
    

    ExecutorService 是一个 Executor,它提供了管理终止的方法和可以生成 Future 以跟踪一个或多个异步任务的进度的方法。

    只要返回的ExecutorService 正在执行正常关闭,就不会有问题。

    您可以通过在您的代码中找到以下内容来检查您的代码是否正在关闭:

    // This will make the executor accept no new threads
    // and finish all existing threads in the queue
    executor.shutdown();
    
    // Wait until all threads are finish
    executor.awaitTermination();
    

    干杯!!

    【讨论】:

    • 我的问题不是以这种方式管理长期存在的应用程序线程是否安全,而是它是否是最佳实践。
    • 可以,只要您注意优雅地关闭并关闭这些线程使用的所有资源。
    【解决方案2】:

    我假设您的长期线程在循环中执行一些周期性工作。您可以执行以下操作:

    1. 确保池中的每个可运行对象在循环之前检查池的状态。

    while( ! pool.isShutdown() ) { ... }

    因此,您的 runnable 必须引用其父池。

    1. 使用Runtime.addShutdownHook() 安装JVM 关闭挂钩。钩子调用pool.shutdown(),然后调用pool.awaitTermination()。池将转换为 SHUTDOWN 状态,最终线程将停止,之后将转换为 TERMINATED 状态。

    --

    也就是说,我对你的 4 个线程有点怀疑。不应该只有 1 个长寿命线程来获取任务并将它们提交给执行器服务吗?你真的有 4 个不同的长寿命进程吗? (这个考虑与主要问题是正交的)。

    【讨论】:

    • 我只是最近继承了这段代码,并没有写。但我认为你的最后一点很好地抓住了我的担忧。我想知道整个设计是否不正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 2017-07-15
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多