Если вы прочитаете несколько реализаций и статей по теме, вы заметите, что есть следующая общая тема:
1) Объекты общего состояния имеют неизменяемый стиль lisp / clojure : все операции записи выполняются, копируя существующее состояние в новый объект, вносят изменения в новый объект и затем пытаются обновить общее состояние (получено из выровненного указателя, который может быть обновлен с помощью примитива CAS). Другими словами, вы НИКОГДА не изменяете существующий объект, который может быть прочитан больше, чем текущий поток. Неизменяемость может быть оптимизирована с использованием семантики копирования при записи для больших и сложных объектов, но это еще одно дерево орехов
2) вы четко указываете, какие допустимые переходы между текущим и следующим состоянием действительны : тогда проверка правильности алгоритма станет на порядок проще
3) Обработка отброшенных ссылок в списках указателей опасности для каждого потока . После того, как контрольные объекты в безопасности, используйте повторно, если это возможно
Смотрите еще один мой связанный пост, где некоторый код, реализованный с помощью семафоров и мьютексов, (частично) переопределён в стиле без блокировки:
Взаимное исключение и семафоры