消费者/生产者问题:由于消耗缓慢而暂停生产
作者:互联网
我有一个生产商,可以从磁盘读取文本块.多个使用者正在对该块进行计算.
如果当前要计算的块超过n个,我希望生产者暂停从磁盘读取数据.
将其放在伪代码中以说明我想要实现的目标.
// "produceBlocks" reads blocks from disk one by one
// and feeds them to lambda
produceBlocks(block -> {
// (!) if activeCounter exceeds a THRESHOLD, then pause
executorService.submit(() -> {
activeCounter.incrementAndGet();
// do some work
activeCounter.decrementAndGet();
});
});
解决方法:
“如果当前正在计算的块数超过n,我希望生产者暂停从磁盘读取数据.”
实际的任务描述略有不同:生产者在从磁盘读取数据之前应获得许可.
如果您的生产者是线程,则用于管理许可证的自然设施为Semaphore.最初,它包含n个许可证.生产者要读取一个块,请向Semaphore :: aquire授予1个许可.当使用者处理该块时,使用者使用Semaphore :: release发行1个许可.
另一种方法是将块和许可结合起来.与从生产者到使用者的输出队列类似,为块创建一个输入阻塞队列.最初放置n个块.生产者要读取一个块,首先要从该队列中取出下一个块.使用者处理完一个块后,将其返回到输入队列.
标签:producer-consumer,concurrency,java 来源: https://codeday.me/bug/20191025/1924710.html