【问题标题】:Java ThreadPoolExecutors idle thread shutdown - calling custom cleanup codeJava ThreadPoolExecutors 空闲线程关闭 - 调用自定义清理代码
【发布时间】:2014-09-26 02:23:35
【问题描述】:

根据 ThreadPoolExecutor 文档 (Java ThreadPoolExecutor),如果我像这样创建执行器服务:

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);

当#threads > corePoolSize 时,空闲线程将被杀死。当 ThreadPoolExecutor 杀死任何线程时,我想调用一些特定于应用程序的清理代码。我无法找到明确的方法来做到这一点。感谢任何帮助。提前致谢。

【问题讨论】:

  • 您是否考虑过为执行器提供您自己的 ThreadFactory 实现,从而创建您自己的“我被杀”——感知线程的实现?
  • 我只是查看了实现,我认为覆盖interrupt 开始清理不是您想要的。当工作线程被“杀死”时,ThreadPool 只会放弃引用,而不必调用中断。反之亦然:当中断被调用时,并不意味着线程被杀死。
  • 我猜你应该让你的 ThreadFactory 保持对它创建的线程的 WeakReferences 并将它们注册到 ReferenceQueue。当它们难以到达时(所有强引用都被放弃),它们就会被排入队列。这就是我会尝试的。也许有人有更好(更简单)的想法?
  • 我从来不需要这个,这让我怀疑你有设计问题。

标签: java multithreading threadpoolexecutor


【解决方案1】:

正确的方法是扩展 Thread 并在 run() 方法返回后运行清理代码,如下所示:

    BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
    ThreadFactory threadFactory = new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r) {
                @Override
                public void run() {
                    super.run();
                    //DO YOUR CLEANUP HERE
                }
            };
        }
    };
    new ThreadPoolExecutor(1, 10, 10, TimeUnit.SECONDS, workQueue, threadFactory);

在您的场景中几乎肯定不会调用中断,因为它只会在关闭活动执行器时被调用(即使那样,也不总是如此)。

通过在运行后直接调用 cleanup,您的清理代码会在线程终止之前被调用(线程在 runnable 的 run() 方法返回后终止)。

【讨论】:

  • 很好的答案只有 1 个缺陷:如果你真的拿到代码并运行它,你最终会在池中只有 1 个线程。这是由于您提供的 ArrayBlockingQueue 工作队列。如果您更改它与 SynchronousQueue 一起使用,答案将是完美的!现在,为什么会这样?这应该是另一个“stackoverflow”问题(如果还没有......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 2014-05-04
相关资源
最近更新 更多