Java中只有一个使用者线程和生产者线程的并发队列

Java中只有一个使用者线程和生产者线程的并发队列,java,multithreading,algorithm,concurrency,queue,Java,Multithreading,Algorithm,Concurrency,Queue,我在应用程序中有原始的消息传递系统。消息可以由生产者从一个线程提交,由消费者在另一个线程中处理-根据设计只有两个线程:一个线程用于消费者,另一个线程用于生产者,并且不可能更改此逻辑 我正在使用ConcurrentLinkedQueue实现来处理消息: //生产者代码(添加请求) this.queue.add(req); //消费者代码(带请求轮询的忙循环) while(true){ Request req=this.queue.poll(); if(req==null){ 继续; } if(re

我在应用程序中有原始的消息传递系统。消息可以由生产者从一个线程提交,由消费者在另一个线程中处理-根据设计只有两个线程:一个线程用于消费者,另一个线程用于生产者,并且不可能更改此逻辑

我正在使用
ConcurrentLinkedQueue
实现来处理消息:

//生产者代码(添加请求)
this.queue.add(req);
//消费者代码(带请求轮询的忙循环)
while(true){
Request req=this.queue.poll();
if(req==null){
继续;
}
if(req.last()){
//消费者提交的最后一个请求
返回;
}
//函数来处理请求
本程序(req);
}
处理逻辑非常快,消费者每秒可能会收到大约
X\u 000
请求

但我发现使用探查器时,
queue.poll()
有时速度非常慢(似乎是队列从生产者那里接收到很多新项目时的速度)-与未从其他线程添加新项目的情况下接收到大量新消息的队列相比,接收到大量新消息时的速度要慢10倍左右


有可能优化它吗?对于这种特殊情况,
Queue
的最佳实现是什么(一个线程用于
poll()
,一个线程用于
add()
)?也许自己实现一些简单的队列更容易些?

生产者生产时,消费者的速度较慢,因为每次读取时,它都会遇到缓存未命中,因为新元素总是存在。 如果所有元素都已存在,则可以将它们提取到一起,从而提高吞吐量

当忙等待考虑使用时:虽然它增加了延迟,但它也能实现某些性能优化。

// consumer's code (busy loop with request polling)
while (true) {
  Request req = this.queue.poll();
  if (req == null) {
    Thread.onSpinWait();
    continue;
  }
  if (req.last()) {
    // last request submitted by consumer
    return;
  }
  // function to process the request
  this.process(req);
}
JDK没有针对SPSC(单生产者单消费者)场景优化的队列。这里有图书馆。您可以使用或。实现这些目标并不容易

// Agrona
Queue<Request> queue = new OneToOneConcurrentArrayQueue<>(2048);
// JCTools
Queue<Request> queue = new SpscArrayQueue<>(2048);
//Agrona
队列队列=新的OneToOneConcurrentArrayQueue(2048);
//JCTools
队列队列=新的SpscArrayQueue(2048);

这是否回答了您的问题@非常感谢您的链接,但我不认为-
LinkedBlockingQueue
对我来说性能更差:我尝试过使用它,但它比非阻塞
ConcurrentQueue
慢2倍多。所以这两种队列实现都不适合我的应用程序。您尝试过SynchronousQueue吗?当一个线程想要将数据传递给另一个线程时,就使用这个类。@Eric,当消费者忙于处理一个元素时,生产者如何能够向队列中添加多个元素来存储它们呢?值得一提的是,我过去在这个场景中成功地使用了一个循环缓冲区,所做的努力相对较少。如果我没记错的话,所需要的只是一个(包装)写索引、一个(包装)读索引和一个监视器变量,供编写器启动等待的读取器。读卡器从不更新写索引,写卡器从不更新读索引。-我记得,我使用的是一个预先分配的固定长度数组。动态调整队列大小可能更复杂。谢谢,我测试了所有建议的解决方案,并选择了Jctools实现
SpscArrayQueue
。它在我的应用程序中显示了最好的性能。