Как я могу проверить, находится ли поток внутри синхронизированного блока или метода? - PullRequest
7 голосов
/ 23 февраля 2011

Мое Java-приложение использует два потока.Исторически сложилось, что используются синхронизированные методы и выделенные объекты блокировки.Мне нужно знать, есть ли у текущего потока блокировка, и если это по методу или объекту.Как я могу это сделать?

Ответы [ 2 ]

18 голосов
/ 23 февраля 2011

При входе в синхронизированный метод виртуальная машина устанавливает блокировку текущего объекта.Таким образом, следующие коды имеют одинаковый эффект:

synchronized void syncMethod() {
    // do something
}

void syncManually() {
    synchronized (this) {
        // do something
    }
}

Это означает, что синхронизированный метод работает точно так же, как

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 более сложные блокировки, такие как ReentrantReadWriteLock , поддерживаются пакетом java.util.concurrent.locks.Они могут обеспечить раздельную блокировку чтения и записи и повысить производительность вашего приложения. Lock Objects глава Oracle Java Tutorials - хорошее начало здесь.

1 голос
/ 23 февраля 2011

Если вы вручную запросите дамп потока, JVM распечатает трассировку стека каждого потока, включая информацию о том, какие объекты / методы заблокированы или ожидают синхронизированный блок.

Вы можете вручную запросить дамп потока, отправив процессу JVM SIGQUIT в * nix или введя CTRL-Break (не Ctrl-C) в окне командной строки Windows, где была запущена JVM.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...