44

特定のオブジェクトのロックを保持しているスレッドの名前を実行時にプログラムでチェックすることは可能ですか?

4

9 に答える 9

29

現在のスレッドが通常のロックを保持しているかどうかだけがわかります ( Thread.holdsLock(Object))。ネイティブ コードがないと、ロックを持つスレッドへの参照を取得できません。

ただし、スレッド化で複雑なことを行う場合は、おそらく java.util.concurrent パッケージに慣れる必要があります。を使用すると、そのReentrantLock所有者を取得できます (ただし、保護されたメソッドであるため、これを拡張する必要があります)。アプリケーションによっては、同時実行パッケージを使用することで、結局ロックの所有者を取得する必要がないことに気付くかもしれません。

スレッド ダンプを stderr に発行するよう JVM に通知するなど、デッドロックの原因を特定するのに役立つ、ロックの所有者を見つけるための非プログラム的な方法があります。

于 2008-09-08T20:21:07.780 に答える
18

あなたは反射で糸によって保持された錠に着くことができます。これはJava1.6でのみ機能します。

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] ti = bean.getThreadInfo(bean.getAllThreadIds(), true, true);

これらの各ThreadInfoオブジェクトには、問題のロックと比較するためにidentityHashCodeを使用できるLockInfoオブジェクトがあります。

于 2009-09-04T07:40:11.667 に答える
7

1.6 から、JMX を使用して、保持されているロックの検索など、あらゆる種類の興味深いことを実行できます。実際のオブジェクトを取得することはできませんが、クラスと ID ハッシュ値 (一意ではありません) は取得できます。

(この投稿にはもともと、現在は機能していない私のウェブログの例へのリンクが含まれていました。)

于 2008-09-09T11:02:25.043 に答える
4

jconsoleを実行します。これは Java SDK に含まれており、コマンド ラインから実行されます。使用しているOSはわかりませんが、WindowsではJavaプロセスのPIDを渡すだけです。問題の原因となっているスレッドを見つけるのに役立ちます。または、YourKit などの商用プロファイラーやその他のプロファイラーを使用することもできます。

于 2008-09-09T03:40:50.283 に答える
3

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を参照してください。

于 2008-09-09T11:13:36.840 に答える
2

再入可能ロックの場合、現在のスレッドによって保持されているかどうかを確認できます

final ReentrantLock lock = new ReentrantLock();
lock.isHeldByCurrentThread();
于 2015-07-11T16:34:13.177 に答える
1

特定のオブジェクトのロックを確認するには、そのオブジェクトに対してwait()またはnotify()メソッドを呼び出します。オブジェクトがロックを保持していない場合は、 がスローされllegalMonitorStateExceptionます。

2- メソッドを呼び出すholdsLock(Object o)。これはブール値を返します。

于 2013-03-07T07:08:22.030 に答える
0

ロックを取得するときに変数を使用して現在のスレッドを保持し、他の誰かがそれを使用しようとしている場合はそれを出力できます。

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;
    }
}
于 2011-12-04T23:21:55.207 に答える