This allows us to have concurrent reads and a single writer. It's simple and effective. The problem I was facing was that my write, while infrequent, could take a relatively long time. This resulted in blocked readers. What I realized though was that, while I needed to serialize writes, much of the writing code could, in fact, be done concurrently with reads. For example, what if we're dealing with an array which we want to append to:

This definitely performs better, but concurrent calls to Append could easily result in lost writes. Don't see how? Imagine we have have an array ["a", "b", "c"] and two calls to Append happen at the same time: Append("d") and Append("e"). Both calls would create a new array with 4 slots, copy the original 3 values and append their respective value. Whichever call got the lock last, would win. However, the desired result would likely be an array with 5 values.

The new lock ensures that writes are serialized, so that one won't stomp another. With this new guardian in place, we can safely use our main lock more finely, allowing concurrent reads even during the slow part (in this case copy) of our write.