如何检查线程是否在同步块或方法中?

我的Java应用程序使用两个Threads。 从历史上看,有使用的同步方法和专用锁定对象。 我需要知道当前线程是否有锁,如果它是方法或对象。 我怎样才能做到这一点?

进入同步方法时,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一章是一个很好的开始。

如果您手动请求线程转储,JVM将打印出每个线程的堆栈跟踪,包括锁定或等待同步块的对象/方法。

您可以通过在* nix中向JVM进程发送SIGQUIT或在启动JVM的Windows命令提示符窗口中键入CTRL-Break (而不是Ctrl-C )来手动请求线程转储。