我的Java应用程序使用两个线程。从历史上看,有使用的同步方法和专用锁定对象。我需要知道当前线程是否有锁,如果是方法或对象。我怎么能这样做?
答案 0 :(得分:18)
当输入同步方法时,VM会在当前对象上设置锁定。因此,以下代码具有相同的效果:
synchronized void syncMethod() {
// do something
}
void syncManually() {
synchronized (this) {
// do something
}
}
这意味着synchronized方法与
完全相同synchronized( lock ) {
// do something
}
代码中的任何位置。
您可以使用Thread.holdsLock(...)
检查线程是否包含特定锁。这是一个示例代码:
final Object lock = new Object();
public void lockDemo() {
System.out.println( Thread.holdsLock(lock) ); // false
System.out.println( Thread.holdsLock(this) ); // false
synchronized ( lock ) {
System.out.println( Thread.holdsLock(lock) ); // true: locked by object
System.out.println( Thread.holdsLock(this) ); // false
}
doSyncMethod();
}
public synchronized void doSyncMethod() {
System.out.println( Thread.holdsLock(lock) ); // false
System.out.println( Thread.holdsLock(this) ); // true: locked by synchronized method
}
自Java 1.5以来,java.util.concurrent.locks
包支持更复杂的锁,如ReentrantReadWriteLock。
它们可以提供独立的读写锁定并提高应用程序的性能。 Oracle Java教程的Lock Objects章节是一个很好的开始。
答案 1 :(得分:1)
如果您手动请求线程转储,JVM将打印出每个线程的堆栈跟踪,包括锁定或等待同步块的对象/方法。
您可以通过在* nix中向JVM进程发送SIGQUIT或在启动JVM的Windows命令提示符窗口中键入CTRL-Break
(而不是Ctrl-C
)来手动请求线程转储。