I was reading a blog post RailGuard about a creative interface for avoiding having to code explicit exception handling around locks. I left a tip.
A couple decades ago I would have agreed that was the solution. I changed my mind after realizing that you very rarely need locks and the typical example scenario is a paper tiger. If you assume you have simultaneous writers (readers don’t need locks just consistency, i.e. what is the state of the world now not what will it be after the current write).
A simple generic non-locking replacement implementation is to make the access to a shared resource (memory) a thread with a thread safe queue (hopefully non-blocking for reads and writes). Start the thread, add the access to the shared resource(memory) to the queue (a reference to the function or method or an object with a standard method or even DSL statement/function). Threaded shared object processes all requests priority FIFO or even writes first or reads first depending on the use case in a loop that sleeps and checks or use a function wrapper that starts the thread on add to queue if not already started and maybe even have the thread stop on empty queue.
Just my horse sense.