2013-02-18 81 views
0

我正在寻找一个线程安全无限阻塞fifo,它由固定缓冲区(如数组)支持。语义是多读者和写者线程可以安全地访问它。如果缓冲区已满并覆盖最旧的项目,写入程序会阻止。如果缓冲区为空,则读取器阻止。当总计添加和总计删除的计数器一次或多次缠绕内部缓冲区大小时,必须保持Fifo顺序。java中的无限fifo

有趣的是,我会寻找这个东西(java自己的并发集合,公共集合,番石榴)通常看不到有这样一个'明显'需求的即时答案。

+3

你的意思是无限的? – 2013-02-18 08:28:12

+0

无限我的意思是随机添加和随机删除总添加和删除远远超过支持数据结构的大小无限。 – simbo1905 2013-02-18 16:35:40

+0

umm,ArrayBlockingQueue _does_维持严格的fifo顺序。你是否尝试启用“公平”构造参数? – jtahlborn 2013-02-18 16:54:13

回答

3

你实际上是在描述一个ArrayBlockingQueue

它是线程安全的,并已设计用于确切目的:

  • 作家等待空间变得可用,如果队列满了,如果有必要
  • 读者可以等待到一个指定的等待时间为一个元素变得可用
+0

感谢您的回答。我尝试的第一件事是ArrayBlockingQueue。当随机添加和随机删除以及溢出和批量插入和批量清除时,单元测试开始失败。我希望fifo订购保证,而不必在外部跟踪订单或尽可能进行排序。 – simbo1905 2013-02-18 16:37:55

+0

我的意思是随机读取/写入逻辑头部和逻辑尾部不是随机的逻辑FIFO中。如果我总是希望缓冲区充分有效,那么循环缓冲区语义看起来像是超出原始ABQ的东西。 – simbo1905 2013-02-18 16:54:23

+0

@ simbo1905 - ABQ _is_是一个循环缓冲区。目前尚不清楚ABQ缺乏哪些功能? – jtahlborn 2013-02-18 16:56:08

0

这听起来像你正在寻找ArrayBlockingQueue

+0

我已编辑的问题,使其更清晰,我正在寻找一些东西,可能是作家覆盖最旧的项目的阻塞循环缓冲区。 – simbo1905 2013-02-18 17:08:50

0

,如果你正在寻找无限阻塞队列或界阻塞队列它是什么并不清楚。

  1. 界阻塞队列:java.util.concurrent.ArrayBlockingQueue中
  2. 无限阻塞队列(仅由RAM约束的限制):java.util.concurrent.LinkedBlockingQueue中

对于所有我会建议使用ArrayBlockingQueue的情况。

+0

感谢您的回答。在其他答案中提示ABQ我表明我更多地寻找一个循环缓冲区,这对ABQ来说不是开箱即用的。 – simbo1905 2013-02-18 16:52:32

+0

哼。我被困在有一个数组,因为我不一定想要添加和删除链接的垃圾回收。但这可能是可以接受的,并且链接阻塞队列可能会诀窍。会给它一个去让你知道。 – simbo1905 2013-02-18 17:12:16

0

对于无限队列你就必须创建自己的类使用队列代表(也许ArrayBlockingQueue),当队列满运行,适应规模实现BlockingQueue接口,创建一个新的,更大的委托。这应该是无限的,最大为MAX_INT,并避免链接队列(需要为每个插入的对象创建节点)涉及的GC开销。如果需要,您也可以缩小委托。

+0

如何保持与很多随机添加和删除fifo订购? – simbo1905 2013-02-18 16:39:26

+0

不确定你在这里是什么意思。在FIFO(a.k.a列表或队列)中,中间不应有随机写入。 – 2013-02-18 16:45:30

+0

道歉我并不是指随机访问,我的意思是从头部或尾部随机读取。如果您尝试使用ArrayBlockingQueue创建一个循环缓冲区,使其保持满,但头部和尾部不在位置0或位置(大小为1)处,请确保始终从逻辑尾部和下一个位置读取下一个从逻辑头读取并不容易,因为在模拟线性结构而不是无限循环缓冲区的结构中调用内置头/方法。 – simbo1905 2013-02-18 16:49:33