我在自己的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 的观点,即代码中的其他地方一定存在同步问题。
我证明一些事情的建议是:
尝试记录
getTaskCount
和getCompletedTaskCount
。 这导致您观察到,在给定时间队列中确实只有 1 个任务。扩展 ThreadPoolExecutor 并使用
afterExecute
Hook ,而不是组合。也许您可以调查谁在同步,但不应该这样。
关于Java - 如何记录线程池中的指标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28698288/