int capacity = ...
BlockingQueue q = new LinkedBlockingQueue<Element>(capacity);
Now, I do feel mildly ridiculous asking this but I'm not particularly savvy when it comes to java concurrency, so I would appreciate some help with choosing the correct way to enqueue something (and dequeue, actually, but I expect when we cleared up the one, the other will fall into place by itself).
There is, of course
while(!q.offer(e));
But I'm a bit wary of spinning implementations in a multi-threaded environment.
And I can't do
synchronized(q){
while(!q.offer(e))q.wait();
}
either because the wakeup calls will go to internal (private) instances of Condition
, meaning this would be a suicide-by-sleeping-pills implementation.
However, I'm also not particularly fond of
try{
q.put(e);
}catch(InterruptedException ex){}
(even though it does seem to be a popular choice in online examples) because although this would do the waiting for me, I know of no reliable way to detect when an exception would force me to try again. I could do something like
boolean success = false;
do{
try{
q.put(e);
success = true;
}catch(InterruptedException ex){}
}while(!success)
But then I'd end up enqueuing the same element multiple times if the exception takes place in-between the put
and the assignment to success
.
I could do
boolean success = true;
do{
try{
q.put(e);
}catch(InterruptedException ex){
success = false;
}
}while(!success)
But I remember having read (way back) that you shouldn't rely on exception handling for conditionals (though I can't seem to remember the reason why this is discouraged).
So ... what options do I have? Do I need to spin or is there something more intelligent?