Есть ли риск в оболочке AutoCloseable для java.util.concurrent.locks.Lock?

С введением try-with-resource в Java 7 я был удивлен, увидев, что что Lock не был преобразован в AutoCloseable. Это казалось довольно простым, поэтому я сам добавил его следующим образом:

class Lock implements AutoCloseable {
    private final java.util.concurrent.locks.Lock _lock;
    Lock(java.util.concurrent.locks.Lock lock) {
        _lock = lock;
        _lock.lock();
    }
    @Override 
    public void close() {
        _lock.unlock();
    }
}

Это работает с классом AutoCloseableReentrantReadWiteLock и используется следующим образом:

try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
    // do something
}        

Поскольку это кажется таким простым и каноническим использованием автоматического закрытия RAII, я думаю, что должно быть хорошее причина, по которой этого делать не следует. Кто-нибудь знает?


person Miserable Variable    schedule 15.05.2013    source источник
comment
@rxg Я собираюсь отменить большую часть вашего редактирования, мое удивление было не тогда, когда оно было представлено, а недавно, когда я использовал его для блокировки   -  person Miserable Variable    schedule 11.06.2013
comment
Нет проблем, но вы можете исправить ссылку для AutoCloseable?   -  person rxg    schedule 12.06.2013


Ответы (1)


Когда в феврале/марте 2009 года был предложен try-with-resources, это вызвало большие споры.

Джош Блох, автор предложения, сказал: «Эта конструкция была разработана для одной цели и только одно: управление ресурсами. Оно не предназначено для блокировки."

Было отдельное предложение прикрыть замки отдельно, но оно никуда не делось.

Я думаю, что основными причинами, по которым блокировки не были покрыты, были:

  • невозможно добавить методы к интерфейсу в Java 7
  • снижение производительности из-за создания дополнительного объекта-оболочки, реализующего правильный интерфейс
  • философские возражения против того, что Lock является ресурсом, отличным от файловых дескрипторов (например, создание Lock не влечет за собой вызов метода lock)

Вы можете следить за всеми историческими спорами на странице архива, например эту тему.

person rxg    schedule 11.06.2013
comment
Благодарю вас за информацию; для меня замок кажется ресурсом, но, возможно, есть вещи, которые я упускаю. Работая в мире Spring, снижение производительности из-за оберток не имеет значения. - person Miserable Variable; 11.06.2013
comment
@MiserableVariable: Блокировка — это ресурс, по крайней мере, для меня и Дейкстры (:D), см., например. описание алгоритма Banker. Нет необходимости каждый раз создавать новый объект (вам нужно только что-то, имеющее метод close, и вы можете использовать его несколько раз). - person maaartinus; 13.12.2013
comment
@maaartinus Боюсь, я не понимаю, что вы говорите. Если у вас есть закрытый метод, вам также нужен открытый метод, что и делает create для класса Lock. - person Miserable Variable; 14.12.2013
comment
@Miserable Variable: вам нужен открытый метод, но он может выглядеть как AutoCloseable open() {lock(); return myCloseable;}, где myCloseable — это конечное поле (и его закрытие, очевидно, разблокирует блокировку). - person maaartinus; 14.12.2013
comment
@MiserableVariable: Извините, я был сбит с толку... вы все делаете правильно. - person maaartinus; 14.12.2013
comment
Этот ответ все еще актуален для Java? - person JFFIGK; 22.11.2019