特定のオブジェクトのロックを保持しているスレッドの名前を実行時にプログラムでチェックすることは可能ですか?
9 に答える
現在のスレッドが通常のロックを保持しているかどうかだけがわかります ( Thread.holdsLock(Object)
)。ネイティブ コードがないと、ロックを持つスレッドへの参照を取得できません。
ただし、スレッド化で複雑なことを行う場合は、おそらく java.util.concurrent パッケージに慣れる必要があります。を使用すると、そのReentrantLock
所有者を取得できます (ただし、保護されたメソッドであるため、これを拡張する必要があります)。アプリケーションによっては、同時実行パッケージを使用することで、結局ロックの所有者を取得する必要がないことに気付くかもしれません。
スレッド ダンプを stderr に発行するよう JVM に通知するなど、デッドロックの原因を特定するのに役立つ、ロックの所有者を見つけるための非プログラム的な方法があります。
あなたは反射で糸によって保持された錠に着くことができます。これはJava1.6でのみ機能します。
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] ti = bean.getThreadInfo(bean.getAllThreadIds(), true, true);
これらの各ThreadInfoオブジェクトには、問題のロックと比較するためにidentityHashCodeを使用できるLockInfoオブジェクトがあります。
1.6 から、JMX を使用して、保持されているロックの検索など、あらゆる種類の興味深いことを実行できます。実際のオブジェクトを取得することはできませんが、クラスと ID ハッシュ値 (一意ではありません) は取得できます。
(この投稿にはもともと、現在は機能していない私のウェブログの例へのリンクが含まれていました。)
jconsoleを実行します。これは Java SDK に含まれており、コマンド ラインから実行されます。使用しているOSはわかりませんが、WindowsではJavaプロセスのPIDを渡すだけです。問題の原因となっているスレッドを見つけるのに役立ちます。または、YourKit などの商用プロファイラーやその他のプロファイラーを使用することもできます。
1.5 では、すべてのスレッドを見つけて、それぞれの状態を取得できます。たとえば、次のようになります。
Map<Thread,StackTraceElement[]> map = Thread.getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> threadEntry : map.entrySet()) {
log.info("Thread:"+threadEntry.getKey().getName()+":"+threadEntry.getKey().getState());
for (StackTraceElement element : threadEntry.getValue()) {
log.info("--> "+element);
}
}
Thread.getState は、スレッドがブロックされているか、待機中かなどについての情報を提供します。jdk api ThreadStateを参照してください。
再入可能ロックの場合、現在のスレッドによって保持されているかどうかを確認できます
final ReentrantLock lock = new ReentrantLock();
lock.isHeldByCurrentThread();
特定のオブジェクトのロックを確認するには、そのオブジェクトに対してwait()
またはnotify()
メソッドを呼び出します。オブジェクトがロックを保持していない場合は、 がスローされllegalMonitorStateException
ます。
2- メソッドを呼び出すholdsLock(Object o)
。これはブール値を返します。
ロックを取得するときに変数を使用して現在のスレッドを保持し、他の誰かがそれを使用しようとしている場合はそれを出力できます。
Thread holderOfLock = null;
Object theLock = new Object();
public void doStuff()
{
if(holderOfLock != null)
{
//get and print name of holderOfLock-thread or get stacktrace etc.
}
synchronized (theLock)
{
holderOfLock = Thread.currentThread();
//do stuff...
holderOfLock = null;
}
}