2016-06-22 15 views
5

Ich habe einen Executor, der für das Konsumieren von Nachrichten von einer ArrayBlockingQueue verantwortlich ist.Was könnte der Grund sein, dass Thread geparkt wird bei java.util.concurrent.ThreadPoolExecutor.getTask

new ThreadPoolExecutor(1, 1, 0L, 
       TimeUnit.MILLISECONDS, 
       new LinkedBlockingQueue<>(1), 
       r -> { 
        return new Thread(r, "Request-Queue-Drainer"); 
       }); 

Anforderungs-Queue-Drainer Thread-Zustand in WAITING (Obwohl Aufgaben auf diesen Thread übermittelt werden). Folgendes ist der Thread-Dump.

Name: Request-Queue-Drainer 
State: WAITING on java.u[email protected]5b4757a2 
Total blocked: 0 Total waited: 8 

Stack trace: 
sun.misc.Unsafe.park(Native Method) 
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) 
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
java.lang.Thread.run(Thread.java:745) 

Was könnte der Grund dafür sein, dass der Thread im Wartestatus war?

+0

Was meinst du, "verantwortlich für das Leeren von Nachrichten aus einer Warteschlange?" Sie erstellen hier einen sehr gewöhnlichen "ThreadPoolExecutor". Sie übergeben ihm eine explizite 'ThreadFactory', aber das einzige, was Ihre' ThreadFactory' anders als die Standard-Thread-Factory tut, ist, dass sie jedem neuen Thread einen speziellen Namen gibt. –

Antwort

4

Der Thread wartet, weil die Warteschlange leer ist. Das tun Pool-Threads: Sie wählen Aufgaben aus der Warteschlange und führen sie aus. Wenn die Warteschlange leer ist, warten sie.


Edit: Es ist etwas anderes, das kann passieren, wenn die Warteschlange leer ist: Die ThreadPoolExecutor in einer Giftpille Nachricht senden kann, die einen Pool Thread verursacht zu sterben, wenn die Zahl der Arbeitnehmer größer ist als die corePoolSize für mehr als keepAlive Zeiteinheiten. Das wird in Ihrem Fall jedoch nicht passieren, weil Sie maximumPoolSize und corePoolSize auf die gleiche Nummer (1) setzen.


Ich erwarte, dass Ihre ThreadPoolExecutor nicht anders von dem einen verhalten, die von Executors.newFixedThreadPool(1) außer zurückgegeben würde, dass Sie nur eine anhängige Aufgabe haben können, und es gibt den Pool einen besonderen Namen fädelt.