哪种 Java 阻塞队列对于单生产者单使用者方案最有效

2022-09-01 02:04:39

我正在开发一个标准的Java系统,对我的生产者有关键的时间要求(1/100毫秒很重要)。

我有一个生产者将东西放在一个阻塞队列中,然后一个消费者拿起这些东西并将其转储到一个文件中。当数据不可用时,使用者会阻止。

显然,阻塞队列是合适的接口,但是如果我想最大限度地降低生产者的成本,我应该选择哪种实际实现?当我把东西放进队列时,我想尽可能少地玩锁定和分配之类的事情,我不介意消费者是否必须等待更长的时间或更努力地工作。

有没有一个实现可以更快,因为我只有一个消费者和一个生产者?


答案 1

好吧,真的没有太多的选择。让我来看看列出的子类

DelayQueueLinkedBlockingDequePriorityBlockingQueueSyncretimQueue都是为需要额外功能的特殊情况而制作的;在这种情况下,它们没有意义。

这只剩下ArrayBlockingQueueLinkedBlockingQueue。如果您知道如何判断是否需要 一个 或 一个 ,您也许可以自己回答这个问题。ArrayListLinkedList

请注意,在 中,“链接节点在每次插入时动态创建”;这可能倾向于将您推向.LinkedBlockingQueueArrayBlockingQueue


答案 2

您可以在Java中编写对延迟敏感的系统,但您必须小心内存分配,线程之间的信息传递和锁定。您应该编写一些简单的测试,以查看这些事情在服务器上花费了多少时间。(它们基于操作系统和内存架构而有所不同)

如果这样做,您可以在高达 99.99% 的时间内获得稳定的操作时间。这不是适当的实时,但它可能足够接近。在交易系统上,使用Java而不是C的成本可能花费100英镑/天,但是用C /C++而不是Java进行开发的成本可能要高得多。例如,就它给我们的灵活性以及它保存的错误数量而言。

您可以相当接近在C程序中执行相同操作时看到的相同数量的抖动。有人称之为“类似C”的Java。

不幸的是,在我工作的服务器上,通过ArrayBlockingQueue在Java中的线程之间传递对象大约需要8微秒,我建议您在服务器上进行测试。一个简单的测试是在线程之间传递 System.nanoTime(),看看它需要多长时间。

ArrayBlockingQueue有一个“功能”,它在每个添加的元素上创建一个对象(尽管没有太多好的理由这样做),所以如果你找到一个不这样做的标准实现,请告诉我。