In a nutshell, I’m writing an application that needs a BlockingQueue implementation that provides both FIFO adds/removes, but also a fast contains method, as I’ll be calling it a TON.
LinkedBlockingQueue gets me most of the way there, but it appears that its contains method runs in linear time, as it is based on AbstractQueue‘s contains method. I didn’t see anything in the Java API that seemed to advertise an LBQ with fast contains out-of-the-box.
What makes things tougher is, my project is on a really severe time crunch (no, this isn’t homework). I could do a quick-and-dirty LBQ extension with a HashSet underneath for fast contains, but I’m still going to have to test it, which could eat up a significant amount of man-hours. I’m wondering if there are any trusted/well-tested libraries out there that provide a LinkedBlockingQueue extension with a contains method that runs in O(1) time…? If not, any other suggestions are welcome.
Thanks again to all who provided input. I ended up coding my own
HashedLinkedBlockingQueueimplementation. Getting the synchronization correct by using the decorator pattern proved much more difficult than anticipated. Adding synchronization to the decorator caused deadlocks to occur under heavy load (particularly,put(E element)andtake()introduced hold-and-wait conditions that previously didn’t exist). When coupled with decreased performance because of unnecessary synchronization, it became apparent that I’d need to spend the time to get it right from scratch.Performance in
add/remove/containsis O(1) but comes with roughly double the synchronization cost of the originalLinkedBlockingQueue– I say “roughly double” because the LBQ uses two locks – one for inserts and one for removes when the queue size is sufficiently large to allow concurrent modification of head and tail. My implementation uses a single lock, so removes must wait for adds to complete and vice versa. Here’s the source code for the class – I have tested each method in both multi-threaded and single-threaded modes, but outside of using this class in my own application, I have not come up with a super-complicated, generalized test. Use at your own risk! Just because it works in my app doesn’t mean there aren’t still bugs: