Как проверить, удерживает ли поток монитор определённого ресурса?
Для проверки того, удерживает ли текущий поток монитор определённого объекта, используется статический метод Thread.holdsLock(Object obj). Метод возвращает true, если текущий поток владеет монитором переданного объекта, и false в противном случае.
Сигнатура
Пример
public static native boolean holdsLock(Object obj);
Пример использования
Пример: проверка владения монитором
public class HoldsLockDemo {
private static final Object lock = new Object();
public static void main(String[] args) {
System.out.println("До synchronized: "
+ Thread.holdsLock(lock)); // false
synchronized (lock) {
System.out.println("Внутри synchronized: "
+ Thread.holdsLock(lock)); // true
}
System.out.println("После synchronized: "
+ Thread.holdsLock(lock)); // false
}
}
Важные особенности
| Аспект | Описание |
|---|---|
| Проверяемый поток | Только текущий – нельзя проверить, удерживает ли монитор другой поток |
Аргумент null |
Выбросит NullPointerException |
Применение в assert |
Часто используется в assertions: assert Thread.holdsLock(lock) |
Влияние на ReentrantLock |
Метод работает только с intrinsic-мониторами (synchronized), но не с java.util.concurrent.locks.Lock – для ReentrantLock используйте lock.isHeldByCurrentThread() |
Аналогия из жизни. Вы держите в руках ключ от комнаты и спрашиваете себя: «Этот ключ у меня?» –
holdsLock()отвечает именно на этот вопрос. Но вы не можете таким способом проверить, у кого в руках другой ключ.
На собеседовании. Этот вопрос часто задают вместе с вопросами о
synchronized. Покажите, что знаете ограничение:holdsLock()работает только для intrinsic-мониторов. ДляReentrantLockесть отдельный методisHeldByCurrentThread(). Также упомяните, чтоholdsLock()полезен в отладочных assertions.