Java Lock.lock() и Lock.lockInterruptibly()
Я хотел бы знать, как блокировки реализованы в Java. В некоторых уроках я обнаружил, что они должны быть реализованы с использованием wait () и notify () / notifyAll () и некоторых логических флагов (это может быть намного сложнее, но в принципе так и должно быть)
class SimpleLock {
private boolean locked=false;
public synchronized void lock() throws InterruptedException {
while (locked)
wait();
locked=true;
}
public synchronized void unlock() throws InterruptedException {
locked=false;
notify();
}
}
но я знаю, что интерфейс Lock определяет два метода: Lock.lock (), который не может быть прерван, и Lock.lockInterruptibly (), который может и выбрасывает InterruptedException, чтобы иметь дело с событием.
Если блокировки были реализованы с использованием wait (), не должны ли они быть прерваны вызовом Thread.interrupt ()?
Так как же на самом деле реализованы блокировки? Я думаю, что они основаны на других низкоуровневых средствах синхронизации Java (например, synchronized и wait () / notify ()), но я не знаю как.
1 ответ
Замки реализованы с использованием другой техники. Они используют AbstractQueuedSynchronizer
под капотом. Он использует LockSupport.park(), который вызывает небезопасные public native void park(boolean var1, long var2)
,
На самом деле потоки ожидают в Lock.lock()
все еще может быть прерван, но это не будет показано пользователю, потому что InterruptedException
не будет брошен. Поток проснется после прерывания, затем сбросит флаг прерывания и попытается снова получить такую же блокировку.
Lock.lockInterruptibly()
действует иначе, когда происходит прерывание, оно генерирует исключение, поэтому пользователь может обрабатывать его так, как он хочет.