BlockingQueue的put()和高并发性

时间:2015-11-26 15:18:25

标签: java concurrency blockingqueue fork-join

我使用Fork / Join Framework并行进行大量计算。 我已经使用简单的记录器实现了Producer-Consumer Pattern,以便在程序计算时创建控制台输出。制作人和消费者分享BlockingQueue并使用put()方法,因此我不会错过更新。

我已经认识到在某些情况下性能很糟糕,VisualVM告诉我put()方法是原因。

如果在将新邮件放入BlockingQueue我的RecursiveTask时必须等待,但ForkJoinPool继续分叉新任务,那么2000-5000任务正在尝试访问put()方法,这会导致非常高的并发性。

有没有正确的方法来处理这种情况?

我想像

if(!blockingQueue.offer(message) {
    blockingQueue.put(message);
}
当使用理论上无限的BlockingQueue时,

可能会更高效。

所以我的问题是:是否有适当且高效的方法将对象放入BlockingQueue而不会丢失更新?

提前谢谢!

1 个答案:

答案 0 :(得分:2)

如果您的池正在生成2000-5000个任务,那么这就是您的问题。一旦许多任务开始,您将开始在BlocingQueue.put中看到线索争用,这会推高put的统计信息。

使用BlockingQueue的重点是,如果消费者比生产者更慢(甚至暂时),那么生产者将阻止直到消费者赶上来。这应该导致上游进程也等待。如果这导致你的上游进程(可能是FJP)淹没系统而不是阻塞那么那将是一个问题。

我建议您使用固定容量的FJP。