Что означает идемпотентный метод и каковы побочные эффекты в случае вызова метода close java.lang.AutoCloseable?

В документации Java метода close () java.lang.AutoCloseable говорится

Обратите внимание, что в отличие от close() метод Closeable, этот close() метод не должен быть идемпотентным. Другими словами, вызов этого метода close более одного раза может иметь некоторый видимый побочный эффект, в отличие от Closeable#close(), который требуется, чтобы не оказывать никакого эффекта, если вызывается более одного раза. Однако разработчикам этого интерфейса настоятельно рекомендуется сделать свои близкие методы идемпотентными.


Что они подразумевают под методом идемпотент и каковы побочные эффекты двойного вызова этого close() метода?

И поскольку интерфейс Closeable расширяется AutoCloseable, почему побочные эффекты не проявляются при закрытии Closeable интерфейса?


person Aniket Thakur    schedule 11.10.2013    source источник
comment
Идемпотентность в контексте программирования означает, что вы можете безопасно повторить операцию. Например, вы можете выдавать один и тот же HTTP-запрос GET несколько раз, не опасаясь побочных эффектов (при условии, что он был правильно реализован на сервере).   -  person John Topley    schedule 11.10.2013
comment
Это означает, что вы можете повторить эту операцию n раз и получить тот же результат, в примере метода Http idempotent GET   -  person RamonBoza    schedule 11.10.2013
comment
@RamonBoza Да, при условии, что сервер не изменяет возвращаемый ресурс, и что веб-клиент не считает запросы, и что время последнего запроса не отслеживается и т. Д. Намного лучшим примером будет public int add(int first, int second) { return first + second; } Два последующих вызова определенно не изменит состояние программы, поскольку программа даже не меняет свое состояние. Другой пример void close() { if (!closed) { file.close(); closed = true; } }, поскольку он меняет состояние при первом вызове, но состояние остается идентичным при последующих вызовах.   -  person Edwin Buck    schedule 11.10.2013
comment
@EdwinBuck Это разумное предположение, потому что запросы HTTP GET (среди прочего) должны быть идемпотентными в соответствии со спецификацией HTTP.   -  person John Topley    schedule 11.10.2013
comment
@JohnTopley Idempotence очень зависит от системы координат. GET должен быть идемпотентным с точки зрения внутреннего состояния сервера. Конечно, точки зрения клиентов различаются, иначе мы никогда не будем повторно посещать одни и те же веб-сайты для ежедневных обновлений. Единственный способ, которым сервер избегает изменения данных, - это то, что сервер делегирует содержимое запроса чему-то с отслеживанием состояния (а именно файловой системе или базовому приложению).   -  person Edwin Buck    schedule 11.10.2013
comment
@EdwinBuck Верно. Я имел в виду состояние на стороне сервера.   -  person John Topley    schedule 11.10.2013


Ответы (4)


Идемпотентность означает, что вы можете применить операцию несколько раз, но результирующее состояние одного вызова будет неотличимо от результирующего состояния нескольких вызовов. Короче говоря, можно безопасно вызывать метод несколько раз. Фактически, второй и третий (и так далее) вызовы не будут иметь видимого влияния на состояние программы.

Итак, если вы закроете этот объект один раз, а он закроется, у вас не будет достаточно информации, чтобы узнать, идемпотентен ли он. Однако, если вы закроете его дважды, и в первый раз он закроется, но во второй раз вызовет исключение, он явно не идемпотентный. С другой стороны, если вы закроете его один раз и закроете дважды, а второе закрытие приведет к тому, что элемент останется закрытым таким же образом (возможно, это noop), тогда он будет идемпотентным.

Один из способов создания идемпотента Closeable может быть следующим:

public class Example implements Closeable {

  private boolean closed;

  public Example() {
    closed = false;
  }

  public void close() {
    if (!isClosed()) {
      closed = true;
    }
  }

  public boolean isClosed() {
    return closed;
  }
}

Теперь очевидно, что если close() вызывается один или несколько раз, все возвраты состояния через isClosed() всегда будут возвращать истину. Следовательно, метод close() будет считаться идемпотентным.

person Edwin Buck    schedule 11.10.2013
comment
Также обратите внимание, что это всего лишь одна интерпретация термина идемпотент. идемпотент имеет другие значения в разных контекстах. - person Pacerier; 11.03.2015
comment
@Pacerier Это также почти дословно совместимое описание первого предложения вашего исправления. Если вы используете математический теоретический подход к анализу вычислений, это все равно это определение, хотя и с небольшими переформулировками f(f(x)) = f(x), что, если вы говорите по математике, означает, что если вы дважды выполняете операцию f на x, это то же самое, что выполнить операцию f на x один раз. - person Edwin Buck; 12.10.2015

Объяснение концепции без кода

Определение независимости Эйнштейна

Если следовать афоризму Эйнштейна, если вы делаете одно и то же и получаете разные результаты, то метод не идемпотентный.

Пример идемпотентности

"Please sir, can I have a pay rise?"

"No"

Всегда один и тот же результат. Просьба о повышении заработной платы - идемпотентная операция.

Примеры с HTTP-запросами:

  • Выполнение get запроса: при правильном выполнении, независимо от того, сколько раз вы отправляете этот запрос, вы получите один и тот же ответ.
  • Например, операция, которая не является идемпотентной, будет делать post запрос на создание ресурса - каждый раз, когда вы это делаете, вы будете изменять состояние приложения, в которое вы публикуете это: новый ресурс будет создаваться каждый раз!
person BKSpurgeon    schedule 05.01.2017

Идемпотентный ГЛОССАРИЙ JAVA

Если методы написаны таким образом, что повторные вызовы одного и того же метода не вызывают дублирования обновлений, метод называется «идемпотентным».

В математике идемпотентный элемент, или для краткости идемпотент, - это все, что при умножении на себя дает результат. Например, единственными идемпотентными действительными числами являются 0 и 1.

В дизайне пользовательского интерфейса кнопку можно назвать «идемпотентной», если нажатие на нее более одного раза будет иметь тот же эффект, что и однократное нажатие. Например, кнопка «Пауза» не является идемпотентной, если она переключает состояние паузы. С другой стороны, если нажатие на нее несколько раз приводит к приостановке системы, а нажатие «Play» возобновляет, тогда «Pause» идемпотентно. Это полезно в интерфейсах, таких как инфракрасные пульты дистанционного управления и сенсорные экраны, где пользователь может не быть уверен в успешном нажатии кнопки и может нажать ее снова. Кнопки вызова лифта тоже идемпотентны, хотя многие думают, что это не так.

Ресурс: - http://www.allapplabs.com/glossary/idempotent.htm

person Rahul Agrawal    schedule 22.02.2017

Методы IDEMPOTENT

HTTP-метод является импотентным, если результат становится одинаковым для каждого вызова. Когда вы вызываете любой запрос n раз, результат будет таким же.

Возьмем пример, когда добавление ZERO к любому числу даст тот же результат.

Методы HTTP делятся на два типа.

  1. Безопасное повторение (Идемпотент)
  2. Невозможно безопасно повторить (Неидемпотентный)

Безопасное повторение (Идемпотент): вызовите метод в любое время, он даст тот же результат. он называется Идемпотентными методами.

GET, PUT, DELETE HTTP-метод, который называется идемпотентным методом. Потому что

Метод GET: получение ресурса. Метод PUT: обновляет один ресурс. Метод DELETE: используется для удаления отдельного ресурса, не влияя на другие ресурсы.

Невозможно безопасно повторить (Неидемпотентно)

Но когда вызывается метод POST. Метод POST будет каждый раз создавать новый ресурс. Поэтому он называется Неидемпотентным

person Abhishek Gupta    schedule 04.07.2021