是否可以在运行时以编程方式检查持有给定对象锁的线程的名称?

有帮助吗?

解决方案

你只能判断当前线程是否持有普通锁(Thread.holdsLock(Object))。如果没有本机代码,您无法获得对具有锁的线程的引用。

但是,如果您正在执行任何复杂的线程操作,您可能需要熟悉 java.util.concurrent 包。这 ReentrantLock 确实允许您获取其所有者(但它是受保护的方法,因此您必须扩展它)。根据您的应用程序,通过使用并发包,您很可能会发现您根本不需要获取锁的所有者。

有一些非编程方法可以查找锁所有者,例如向 JVM 发送信号以向 stderr 发出线程转储,这对于确定死锁的原因很有用。

其他提示

您可以通过反射获取线程持有的锁。这只适用于 java 1.6。

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

在每个 ThreadInfo 对象上都有 LockInfo 对象,您可以使用它们的identityHashCode 来与相关锁进行比较。

从 1.6 开始,您可以使用 JMX 来做各种有趣的事情,包括查找持有的锁。您无法获得实际的对象,但您确实可以获得类和身份哈希值(这不是唯一的)。

我的一篇博客中有一个例子。

跑步 控制台. 。它包含在 Java SDK 中并从命令行运行。我不确定你使用的是什么操作系统,但在 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 为您提供有关线程是否被 BLOCKED、WAITING 等的信息,请参阅 jdk api 线程状态

您可以通过调用来检查特定对象上的锁定 wait() 或者 notify() 该对象上的方法。如果对象没有持有锁,那么它将抛出 llegalMonitorStateException .

2- 通过致电 holdsLock(Object o) 方法。这将返回布尔值。

如果是 可重入锁 你可以检查它是否被当前线程持有

final ReentrantLock lock = new ReentrantLock();
lock.isHeldByCurrentThread();

当您获取锁时,您可以使用变量来保存当前线程,然后在其他人尝试使用它时打印它。

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;
    }
}

丑陋但有效。

String findLockOwner(ReentrantLock lock) {
    String patternStr = "\\[Locked by thread (\\S+)\\]";
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher = pattern.matcher(lock.toString());
    boolean matchFound = matcher.find();
    if (matchFound && matcher.groupCount() >= 1) {
      return matcher.group(1);
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top