I have an atom wrapping a vector of items:
(def items (atom [1 2 3 4]))
I want to atomically remove the first item and return it. This code illustrates the logic:
(let [x (first @items)]
(swap! items #(subvec % 1))
x)
But the above code is not correct when many threads are contending with each other. There is a race condition between reading and updating.
As stated nicely in this answer, atoms are for uncoordinated synchronous access. I was hoping this could be done with an atom instead of a ref, because the atom is simpler.
Is there a solution that uses only atoms, not refs? (I'm going to try using watches and see how that goes.) If your answer insists that a ref is needed, could you please explain why a ref is needed even though refs are suggested when one wants "Coordinated Synchronous access to Many Identities" (same link as above).
This is different from other related questions such as How do I update a vector element of an atom in Clojure? and Best way to remove item in a list for an atom in Clojure because I want to update a vector atom and return the value.