That's my point, isn't it better to use a proven solution instead of rolling your own? You also get batch processing, configurable wait strategies and dependency chaining out of the box.
Maybe you're right. I don't know, it just seemed like a bit of an overkill if all I needed was one consumer. I didn't need dependency chaining and configurable wait strategies, and the only wait strategy I needed wan't supported by the disruptor anyway -- fiber-blocking -- so I would have had to do that myself. Also, I wanted to have primitive-type bounded queues, and unbounded queues, too, so an existing solution for one specific type of queue wouldn't have saved much work. You can look at my implementation here
. It's about 300 lines in total. Primitive queues require a bit more work. See here
. (Those are just the bounded queues).
Actually, I just remembered, there was one tricky issue here. The consumer holds a pointer to the last item it read in the queue (I use this for selective receives), and because I use both bounded and unbounded queues, that pointer could be either an index or a ref to a linked-list node, so it's gotta be an Object. In the bounded queue case, Martin's queue uses a long index which always increases; the actual index in the array is that index mod the array length. That meant that any time the consumer read a value, a boxed long would have had to be created and could have been held for a long time (i.e., could be promoted GC-wise). I do something a bit ugly. Internally I use Martin's long-index approach, but I give the consumer an int index, which is equal to the actual array index. This keeps the index always to a small int (always less than the size of the array), so increasing Integer's default maximal cached Integer by just a bit, ensures that a the boxed Integer instance is always cached.