我正在使用Fork/Join框架并行地进行大量计算。我用一个简单的记录器实现了生产者-消费者模式,以便在程序计算时创建控制台输出。生产者和消费者共享一个BlockingQueue,我使用put()方法,这样我就不会错过一个更新。
我已经认识到,在某些情况下,性能非常糟糕,VisualVM向我展示了put()方法是造成这种情况的原因。
当在BlockingQueue中输入新消息时,我的RecursiveTask不得不等待,但是ForkJoinPool继续生成新任务,所以2000-5000个任务试图访问put()方法,这会导致很高的并发性。
是否有适当的方法来处理这种情况?
我以为
if(!blockingQueue.offer(message) {
blockingQueue.put(message);
}当使用理论上无限制的BlockingQueue时,可能会有更好的性能。
因此,我的问题是:是否有一种正确的、可执行的方法将对象放入BlockingQueue而不丢失更新?
提前谢谢你!
发布于 2015-11-26 15:27:39
如果您的池正在生成2000-5000项任务,那么这就是您的问题。一旦许多任务开始执行,您将开始看到BlocingQueue.put中的线程争用,这将提高put的统计信息。
使用BlockingQueue的全部目的是,如果使用者比生产者慢(甚至是暂时的),那么生产者将阻塞直到消费者赶上为止。这将导致上游进程也等待。如果这导致您的上游进程(想必是FJP)坦克系统,而不是只是堵塞,那么这将是一个问题。
我建议你用固定容量的FJP。
https://stackoverflow.com/questions/33941998
复制相似问题