Java: как проверить, можно ли заблокировать блокировку?

Если я хочу обеспечить эксклюзивный доступ к объекту в Java, я могу написать что-то вроде этого:

...
Zoo zoo = findZoo();
synchronized(zoo)
{
    zoo.feedAllTheAnimals();
    ...
}

Есть ли способ проверить, заблокирован ли объект в данный момент? Я не хочу, чтобы мой поток дождался, если другой поток обратится к zoo. Если zoo не заблокирован, я хочу, чтобы мой поток приобрел блокировку и выполнил блок synchronized; Если нет, я хочу, чтобы он пропустил его.

Как я могу это сделать?

Ответ 1

Вы не можете сделать это, используя встроенную в Java низкоуровневую синхронизацию. Но вы можете сделать это, используя API высокого уровня, предоставляемые в параллельном пакете.

Lock lock = new ReentrantLock();
....
//some days later
....
boolean isLocked = lock.tryLock();

Ответ 3

Вы можете сделать это вручную. Хотя у вас уже есть удовлетворительный ответ с ReentrantLock;)

private boolean flag;
private final Object flagLock = new Object();
private final Object actualLock = new Object();

//...

boolean canAquireActualLock = false;
synchronized (flagLock) {
    if (!flag) {
        flag = canAquireActualLock = true;
    }
}
if (canAquireActualLock) {
    try {
        synchronized (actualLock) {

            // the code in actual lock...

        }
    } finally {
        synchronized (flagLock) { flag = false; }
    }
}

Конечно, вы можете обернуть удобными методами.