2012-09-10 28 views
21

這是我的代碼:爲什麼LinkedBlockingQueue#poll()可能會掛斷?

// 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()我立刻達到同樣的情況。

+3

這很可能是一個錯誤,我會嘗試OpenJDK 7或Oracle Java 7更新7的最新版本。因爲這使用系統調用,所以我還要確保您有支持的操作系統版本。 –

+0

你可以在'WAITING'狀態下顯示線程的堆棧跟蹤嗎? – axtavt

+0

你能寫一個可重現的簡單程序嗎? –

回答

3

這是一個在Java 7的早期版本中已經解決的[討厭]問題。如果您遷移到較新的JVM,您將不會遇到這個問題(看起來修復程序未被移植到Java 6 )。

請參閱herehere