java - 为什么 LinkedBlockingQueue#poll() 可能会挂断?

标签 java multithreading concurrency openjdk

这是我的代码:

// in constructor
BlockingQueue<Node> queue = new LinkedBlockingQueue<Node>();
// later in another thread
Node node = queue.poll(1, TimeUnit.SECONDS);

通常它可以工作,但有时,在某些情况下(仍然不知道何时以及为什么) poll() 方法不会返回 NULL 而是保留其线程永远处于 WAITING 状态。为什么以及如何会发生这种情况?

我试过 ArrayBlockingQueue - 效果一样。我在 Mac OS 上使用 OpenJDK:

java version "1.7.0_05" 
Java(TM) SE Runtime Environment (build 1.7.0_05-b06)
Java HotSpot(TM) 64-Bit Server VM (build 23.1-b03, mixed mode)

相同的代码可以在 Mac OS 上使用 Oracle Java 1.6。这是线程卡住的地方:

sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:894)
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1221)
java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:340)
java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:462)

有趣的是,当我 interrupt() 这个线程并再次尝试 poll() 时,我立即遇到了同样的情况。

最佳答案

这是一个在 Java 7 的早期版本中已解决的 [讨厌的] 问题。如果您迁移到较新的 JVM,您将不会遇到该问题(似乎该修复尚未向后移植到 Java 6) .

herehere .

关于java - 为什么 LinkedBlockingQueue#poll() 可能会挂断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12349881/

相关文章:

java - 我的容器如何注入(inject)未标记为@stateful/@stateless等的bean?

java - runtime.getruntime.exec 的内存问题

java - 有没有办法在 Java 中重新初始化静态类?

java - 编译 Java 使其表现得像 GO 代码

c# - 什么时候应该使用 Task.Run()?

java - 在 JSP 中获取当前文件名

c# - Thread.Join 与 Task.Wait

c++ - 为什么它不会发生死锁?

C++ 设置/获取方法同步

java - Hibernate Session#merge 在收到带有 ID 的实体时是否应该插入?