【发布时间】:2014-01-25 20:10:15
【问题描述】:
我正在使用 RabbitMQ,它默认使用 LinkedBlockingQueue 作为消费者。
它有一个阻塞的nextDelivery() 方法,基本上调用队列中的take()。
但如果在调用该方法之前被中断,它不会捕获中断。
if (Thread.interrupted()) {
throw new InterruptedException();
}
// If interrupted here, call below will not throw interrupted exception
rabbit.nextDelivery();
只有在等待时中断命中——这也是 javadoc 中所写的——或者如果先阻塞则命中。
Throws:
InterruptedException - if interrupted while waiting
我实际上有一个案例,中断恰好在我标记的地方命中。如果我在开始或中间设置睡眠,它会起作用,但假设它总是会起作用仍然是不安全的。
是否有替代 BlockingQueue 实现解决此问题? 我不知道它是否消耗了中断,也许静态方法中存在竞争条件它返回false但以某种方式清除设置值?
编辑:这与Thread.interrupted() 通话或不设置标志无关。如果你注释掉 if block,它又是同样的问题。队列方法一进入就不会抛出InterruptedException,它只是阻塞
【问题讨论】:
-
如果
LinkedBlockingQueue.take()没有抛出,则Thread上的中断位未设置。如果有帮助,我会稍微修改一下我的答案。 -
有没有可能
RabbitMQ使用它自己的LinkedBlockingQueue而不是java.util.concurrent中的那个? -
我刚刚在rabbit调用之前调用了
System.out.println(Thread.currentThread().isInterrupted());,它打印了true(这不是清除位),然后rabbit再次阻塞。所以你是对的,它可能是关于兔子的,我正在调查它 -
与其试图搞清楚 Rabbit 的 nextDelivery() 调用的内部操作(谁知道或关心它正在使用什么队列植入),您应该告诉我们您正在尝试做什么,您认为您需要能够拦截线程的中断状态。
-
如果是这种情况,那么
rabbit调用正在清除中断状态之前 调用LinkedBlockingQueue.take()。我在他们的源代码中找不到nextDelivery()。rabbit是什么类型?那不是你的代码?
标签: java concurrency interrupt blockingqueue interrupted-exception