I'm using RabbitMQ which uses LinkedBlockingQueue
by default for consumer.
It has a blocking nextDelivery()
method which basically calls take()
on queue.
But it doesn't catch the interrupt if it was interrupted just before calling that method.
if (Thread.interrupted()) {
throw new InterruptedException();
}
// If interrupted here, call below will not throw interrupted exception
rabbit.nextDelivery();
It only works if interrupt hits while it is waiting -which is what is written in javadoc too- or if hits if block first.
Throws:
InterruptedException - if interrupted while waiting
I actually have a case where interrupt hits just where I marked. It works if I put a sleep to beginning or in between but it's still not safe to assume it will always work.
Is there an alternative BlockingQueue implementation addresses this issue? I don't know if interrupt it consumed or not, maybe there is a race condition in static method it returns false but clears the set value somehow?
Edit: It is not about Thread.interrupted()
call or not setting flags. If you comment out if block, it is same issue again. Queue method doesn't throw InterruptedException
as soon as it enters, it just blocks
So if I'm understanding, your question, then something is swallowing an
InterruptedException
or clearing the interrupt flag. The following code always throwsInterruptedException
for me.It is important to realize that when the
InterruptException
is thrown, the interrupt flag is cleared. You should always do something like:See: Why invoke Thread.currentThread.interrupt() when catch any InterruptException?
What often happens is that 3rd party code does not propagate the interrupt status because of bad code. Then you are often SOL since the interrupt will have been swallowed and the
take()
method will not throw.Also, it is important to realize that
Thread.interrupted()
clears the interrupt flag. Typically you want to useThread.currentThread().isInterrupted()
to test for the status of the interrupt flag.I'm not sure there is an issue.