我在Java中有一个文本处理应用程序,它通过块(~100000行)读取文件块并在单独的线程中处理每个块。
效果很好,但有一个问题。读取行比处理它们要快得多,程序最终会有一个Runnables队列等待轮到他们。这需要一些我打算保存的记忆。
我希望程序能够采用这种方式:
这将使Runnables忙,但同时保留内存以进行处理(而不是存储块)。
我如何用Java做到这一点?写在preudocode我想要这个:
loop {
chunk = readChunkOfData();
counter.inc();
processAsync(chunk);
if (counter.isBiggerThan(16)) {
counter.sleepWhileCounterIsBiggerThan(12);
}
}
...
worker {
// do the job
counter.dec();
}
答案 0 :(得分:1)
正如Marko Topolnik评论的那样,使用有界(阻塞)queues可以优雅地解决您的问题。
你不需要计数器,因为队列知道它的限制,你的伪代码最终会看起来像下面这样
loop {
chunk = readChunkOfData();
queue.put(chunk);
}
worker {
chunk = queue.take();
process(chunk);
}
这假设队列是例如new ArrayBlockingQueue(16);
并且由所有工作人员共享。您还可以使用工作中的drainTo(Collection<? super E> c, int maxElements)
一次性获取多个块,作为工作方的额外工作缓冲区,但这可能不会产生太大影响。