Java - 如何记录线程池中的指标?

标签 java logging threadpool guice

我在自己的ExecutorService实现中封装了一个ThreadPoolExecutor,只是为了向它发送任何文件系统写入任务,这样它们就会被顺序地、一一地处理。 (不用再去骚扰这个可怜的写盘磁头了。)

包装器可以通过以下方式派上用场:

  • 允许我将这个线程池作为 Guice Singleton 注入(inject)到几乎所有我需要的地方
  • 实时告诉我还有多少工作要做

最后一个功能是通过调用 logUtils.writingHeartbeat(int) 来完成的,如果自上次记录以来已经过了“足够”的时间,它会记录一条消息,说明队列中仍有多少作业。它在以所需的时间间隔写入日志方面工作得很好,但总是告诉我还有 0 个文件需要写入。考虑到执行时间,这听起来很可疑。

我做错了什么?

@Singleton
public class WritersThreadPool implements ExecutorService {

    private final ThreadPoolExecutor innerPool;
    private final LogUtils logUtils;

    @Inject
    public WritersThreadPool(LogUtils logUtils) {
        innerPool = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        this.logUtils = logUtils;
    }

    @Override
    public Future<?> submit(final Runnable r) {
        return innerPool.submit(new Callable<Void>() {
            @Override
            public Void call() throws Exception {
                r.run();
                logUtils.writingHeartbeat(innerPool.getQueue().size());
                return null;
            }
        });
    }

    (...) // Other implemented methods with no special behavior.
}

最佳答案

我同意@chubbsondubs 的观点,即代码中的其他地方一定存在同步问题。

我证明一些事情的建议是:

  • 尝试记录 getTaskCountgetCompletedTaskCount。 这导致您观察到,在给定时间队列中确实只有 1 个任务。

  • 扩展 ThreadPoolExecutor 并使用 afterExecute Hook ,而不是组合。也许您可以调查谁在同步,但不应该这样。

关于Java - 如何记录线程池中的指标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28698288/

相关文章:

java - 通过Runnable任务获取自定义Thread的属性

java - JSP编译和Weblogic 10.3.4

node.js - 如何使用 Winston for Node JS 在每个日志行中记录请求和事务 ID?

python-3.x - 在 StreamHandler 的 logging.basicConfig 中设置的自定义格式

c# - 在 C# 中替代 Thread.Sleep?

java - 多线程文件处理和数据库批量插入

java - 如何将 .java 或 .jar 文件转换为 Linux 可执行文件(没有 .jar 扩展名,这意味着它不是 .jar 文件)

java - 需要无用的接口(interface)替代方案

java - 使用selenium查找页面源

log4j 到 logback(迁移)