Java - 如何从ThreadPool中记录指标?

时间:2015-02-24 14:24:25

标签: java logging threadpool guice

我将 ThreadPoolExecutor 包装在我自己的 ExecutorService 的实现中,只是为了向它发送任何文件系统编写任务,所以它们将按顺序排列并逐个处理一。 (不需要骚扰这个可怜的磁盘写头。)

包装器派上用场:

  • 允许我在任何我需要的地方注入这个ThreadPool作为Guice Singleton
  • 实时告诉我还剩下多少工作要做

最后一个功能是通过调用 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.
}

2 个答案:

答案 0 :(得分:1)

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

我建议证明一些事情是:

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

  • 而不是组合,扩展ThreadPoolExecutor并使用afterExecute钩子。也许你可以调查那个不应该同步的人。

答案 1 :(得分:0)

所以我认为问题是你在完全运行提交的Runnable后依次检查队列大小。所以Runnable完全完成了它的工作,然后检查队列大小,除非你已经用尽了innerPool中的线程数,否则它将是空的。换句话说,队列中必须有一些东西等待它打印出除0之外的任何东西。当前作业由一个线程运行,因此它不在队列中。