Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
invalidate(), а другая в это время вызывает get(), результат непредсказуем.update() меняет какое-либо состояние.public class Locker {
private boolean lock;
/**
* Checks if instance is locked.
*
* @throws IllegalStateException if instance is locked
*/
public synchronized void check() {
if (lock) {
throw new IllegalStateException("Locked");
}
}
/**
* Locks instance to prevent use it again.
*
* @throws IllegalStateException if instance is locked
*/
public synchronized void lock() {
check();
lock = true;
}
/**
* Unlocks instance.
*/
public synchronized void unlock() {
lock = false;
}
}
...
try {
// выполняем обновление
locker.lock()
value = update();
locker.unlock()
}
...
public ValueType get() {
// выполняем update() только если значение устарело
if (isInvalid) {
// этот флаг обязательно нужно снять по выходу из update()
try {
locker.lock();
// выполняем обновление
value = update();
// isInvalid станет false только если update()
// выполнился штатно без эксепшенов
isInvalid = false;
} catch (IllegalStateException e) {
throw new RecursionDetectedException(this, e);
} finally {
// снимаем флаг в любом случае, как бы не завершилась get()
locker.unlock();
}
}
return value;
}
public void check() {
if (lock.get()) {
/* Some code here */
}
}
Предотвращение рекурсии и ленивые вычисления в Java