У меня есть атом, обертывающий вектор элементов:
(def items (atom [1 2 3 4]))
Я хочу атомизировать первый элемент и вернуть его. Этот код иллюстрирует логику:
(let [x (first @items)]
(swap! items #(subvec % 1))
x)
Но приведенный выше код неверен, когда многие потоки соперничают друг с другом. Существует условие гонки между чтением и обновлением.
Как было сказано в этом ответе, атомы для нескоординированного синхронного доступа. Я надеялся, что это можно сделать с атомом вместо ref, потому что атом проще.
Есть ли решение, которое использует только атомы, а не refs? (Я собираюсь попробовать использовать часы и посмотреть, как это происходит.) Если ваш ответ настаивает на необходимости ссылки, не могли бы вы объяснить, почему требуется ref, хотя ссылки предлагаются, когда требуется "Скоординированный синхронный доступ ко многим идентификаторам" "(такая же ссылка, как указано выше).
Это отличается от других связанных вопросов, таких как Как обновить векторный элемент атома в Clojure? и Лучший способ удалить элемент в списке для атома в Clojure, потому что я хочу обновить векторный атом и вернуть значение.