Posted by hjohn
on June 18, 2007 at 7:56 AM PDT
I have this use case for a LinkedBlockingQueue, that I can't get to work because of what seems to be limitations in the concurrency package. Since a lot of time went into this new system, I can't help but wonder if I'm doing something wrong or perhaps am missing the point.
Want I want is this:
I have a LinkedBlockingQueue on which a thread waits using the take() method. There are two use cases for this queue:
1) I want to add something to the queue and want it processed when my thread gets to it adding as much items as you want -- so far so good, works like a charm.
2) I want to add something to the queue, but only if the queue is currently empty (the use case is: the user wants to start a certain task immediately, but is only allowed to do so when no tasks are currently running or queued).
No matter what I do, case 2 won't work with LinkedBlockingQueue (atleast not in a thread safe manner).
For example, I tried doing this:
o = queue.take();
// do stuff
Surprisingly, this code deadlocks on isEmpty(). For some reason, the take() method wants to obtain the synchronized lock on queue, which is not possible because Thread 2 already has it. I assume this is because internally isEmpty() wants to obtain the internal lock of the queue, and to get it Thread 1 has to wake up for a second.
This means there is no way to externally synchronize action to be taken on a queue, and since there is no way to get the internal lock the queue uses (it is not even available to subclasses) I can't add this functionality some other way either.
The only option left as far as I can see is to write my own BlockingQueue, but I'm hoping someone here has a better solution.