java - ESPERANDO en sun.misc.Unsafe.park(Método nativo)
multithreading concurrency (3)
Del seguimiento de la pila queda claro que, el subproceso ThreadPoolExecutor> Worker se inició y está esperando a que la tarea esté disponible en el BlockingQueue (DelayedWorkQueue) para seleccionar la tarea y ejecutar. SIGNAL del hilo editor.
Una de mis aplicaciones se cuelga durante un período de ejecución bajo carga, ¿alguien sabe qué podría causar dicha salida en jstack:
"scheduler-5" prio=10 tid=0x00007f49481d0000 nid=0x2061 waiting on condition [0x00007f494e8d0000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000006ee117310> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1085)
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Estoy viendo esto mucho en la salida jstack cuando se cuelga.
Uso intensamente Spring @Async y mapas, mapas sincronizados y ehcache.
Lo interesante es que esto solo sucede en una de las instancias de la aplicación. Otros dos están funcionando perfectamente bien. ¿Qué más podría investigar para obtener más detalles en tal caso?
Encontré esta publicación https://stackoverflow.com/questions/23992787/parking-to-wait-for-0xd8cf0070-a-java-util-concurrent-locks-abstractqueueds pero no es muy útil en mi caso.
Tuve un problema similar, y siguiendo las respuestas anteriores (¡gracias!), Pude buscar y encontrar cómo manejar correctamente la terminación ThreadPoolExecutor.
En mi caso, eso solo corrige mi aumento progresivo de subprocesos bloqueados similares:
- He usado
ExecutorService::awaitTermination(x, TimeUnit)
yExecutorService::shutdownNow()
(si es necesario) en mi cláusula finally. Para obtener información, he usado los siguientes comandos para detectar el número de hilos y enumerar los hilos bloqueados:
ps -u javaAppuser -L | wc -l
jcmd `ps -C java -o pid =` Thread.print >> threadPrintDayA.log
jcmd `ps -C java -o pid =` Thread.print >> threadPrintDayAPlusOne.log
cat threadPrint * .log | grep "pool-" | wc -l
unsafe.park es prácticamente lo mismo que thread.wait, excepto que usa un código específico de la arquitectura (por lo tanto, la razón es ''insegura''). unsafe no está disponible públicamente, pero se usa en bibliotecas internas de java donde el código específico de la arquitectura ofrecería importantes beneficios de optimización. Se utiliza mucho para agrupar hilos.
Entonces, para responder a tu pregunta, todo lo que está haciendo el hilo es esperar algo, en realidad no está usando ninguna CPU. Teniendo en cuenta que el seguimiento de su pila original muestra que está utilizando un bloqueo, asumiría que se está produciendo un interbloqueo en su caso.
Sí, ya sé que es casi seguro que ya hayas resuelto este problema. Sin embargo, eres uno de los mejores resultados si alguien hace googles en sun.misc.unsafe.park. Me imagino que responder a la pregunta puede ayudar a otros a tratar de entender qué es este método que parece estar utilizando toda su CPU.