Javaスレッドダンプでは、スタックトレース内で言及されたロックを確認できます。
3種類の情報があるようです:
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)
組み込みロックを使用する場合はスレッドダンプで「ロック待ち」となり、Java.util.concurrentからのロックを使用する場合は「待機待ち」となります。次の例について考えてみます。
_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();
}
}
_
lockTest.intrinsicLock()
を使用すると、次のスレッドダンプが取得されます。
_"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)
_
lockTest.reentrantLock()
が生成する間:
_"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)
_
私の考えでは、Java.util.concurrentパッケージは、LockSupport.park()メソッドを使用して、abstractqueuedsynchronizedフレームワークに属するCountDownLatch、ReentrantLockなどのスレッドをブロックします。したがって、質問の3番目のシナリオは、コードが最終的にLockSupport.park()メソッドを呼び出すことを意味します。Java.util.concurrentパッケージのコンカレントクラスを使用する場合、2番目のシナリオは、同期されたキーワークを使用してwait()メソッドを明示的に呼び出すことを意味します。