Questo è il mio codice:Perché LinkedBlockingQueue # poll() potrebbe riagganciare?
// in constructor
BlockingQueue<Node> queue = new LinkedBlockingQueue<Node>();
// later in another thread
Node node = queue.poll(1, TimeUnit.SECONDS);
Di solito funziona, ma a volte, in alcune circostanze (ancora non si sa quando e perché) poll()
metodo non restituisce NULL
, ma mantiene il suo filo in WAITING
stato per sempre. Perché e come potrebbe accadere?
Ho provato ArrayBlockingQueue
- lo stesso effetto. Sto usando OpenJDK per Mac OS:
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)
Lo stesso codice funziona bene con Oracle Java 1.6 su Mac OS. Questo è dove i fili sono bloccati:
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)
La cosa interessante è che quando ho interrupt()
questa discussione e cercare di poll()
nuovo raggiungo subito la stessa situazione.
Questo è probabilmente un bug, vorrei provare l'ultima versione di OpenJDK 7 o Oracle Java 7 update 7. Poiché questo utilizza una chiamata di sistema, vorrei anche assicurarmi di avere una versione supportata del sistema operativo. –
Puoi mostrare uno stacktrace del thread nello stato 'WAITING'? – axtavt
È possibile scrivere un programma semplice riproducibile. –