我使用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
而不会丢失更新?
提前谢谢!
答案 0 :(得分:2)
如果您的池正在生成2000-5000个任务,那么这就是您的问题。一旦许多任务开始,您将开始在BlocingQueue.put
中看到线索争用,这会推高put
的统计信息。
使用BlockingQueue
的重点是,如果消费者比生产者更慢(甚至暂时),那么生产者将阻止直到消费者赶上来。这应该导致上游进程也等待。如果这导致你的上游进程(可能是FJP)淹没系统而不是阻塞那么那将是一个问题。
我建议您使用固定容量的FJP。