java - full - thread dump analyzer
Volcado de hilo Java: ¿diferencia entre "esperar para bloquear" y "estacionamiento para esperar"? (2)
En mi opinión, el paquete java.util.concurrent casi usa el método LockSupport.park () para bloquear el hilo, como CountDownLatch, ReentrantLock que pertenecen a abstractqueuedsynchronized framework. Por lo tanto, el tercer escenario en sus preguntas significa que su código finalmente llama al método LockSupport.park (), para usar la clase concurrente en el paquete java.util.concurrent, el segundo escenario significa que utiliza la clave sincronizada y el método wait () explícitamente.
En un volcado de subprocesos de Java, puede ver los bloqueos mencionados dentro de los seguimientos de pila.
Parece que hay tres tipos de información:
1:
- locked <0x00002aab329f7fa0> (a java.io.BufferedInputStream)
2:
- waiting to lock <0x00002aaaf4ff6fa0> (a org.alfresco.repo.lock.LockServiceImpl)
3:
- parking to wait for <0x00002aaafbf70bb8> (a java.util.concurrent.SynchronousQueue$TransferStack)
- 1: El hilo ha obtenido un bloqueo en el objeto 0x00002aab329f7fa0.
- 2 y 3: parece decir que el hilo está esperando que el bloqueo en dicho objeto esté disponible ...
pero ¿cuál es la diferencia 2 y 3?
Obtendrá "esperando bloquear" en el volcado de subprocesos cuando use bloqueos intrínsecos y "estacionamiento para esperar" cuando use bloqueos de java.util.concurrent. Considere el siguiente ejemplo:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
final Lock lock = new ReentrantLock(true);
synchronized void intrinsicLock() {
Thread th = new Thread(new Runnable() {
public void run() {
intrinsicLock();
}
}, "My thread");
th.start();
try {
th.join();
} catch (InterruptedException e) {
}
}
void reentrantLock() {
lock.lock();
Thread th = new Thread(new Runnable() {
public void run() {
reentrantLock();
}
}, "My thread");
th.start();
try {
th.join();
} catch (InterruptedException e) {
}
lock.unlock();
}
public static void main(String[] args) {
LockTest lockTest = new LockTest();
lockTest.intrinsicLock();
//lockTest.reentrantLock();
}
}
Con lockTest.intrinsicLock()
obtendrá el siguiente volcado de hilo:
"My thread" prio=10 tid=0x00007fffec015800 nid=0x1775 waiting for monitor entry [0x00007ffff15e5000]
java.lang.Thread.State: BLOCKED (on object monitor)
at LockTest.intrinsicLock(LockTest.java:9)
- waiting to lock <0x00000007d6a33b10> (a LockTest)
at LockTest$1.run(LockTest.java:11)
at java.lang.Thread.run(Thread.java:662)
mientras que lockTest.reentrantLock()
produce:
"My thread" prio=10 tid=0x00007fffec082800 nid=0x17e8 waiting on condition [0x00007ffff14eb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d6a33d30> (a java.util.concurrent.locks.ReentrantLock$FairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:842)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1178)
at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:201)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
at LockTest.reentrantLock(LockTest.java:22)
at LockTest$2.run(LockTest.java:25)
at java.lang.Thread.run(Thread.java:662)