21

これは私のコードです:

// 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()再試行すると、すぐに同じ状況に到達することです。

4

1 に答える 1

3

これは [厄介な] 問題で、Java 7 の初期バージョンで解決されています。新しい JVM に移行すると、その問題は発生しません (修正が Java 6 にバックポートされていないようです)。

ここここを参照してください。

于 2012-09-20T10:21:32.890 に答える