Представьте, что вы пишете банковское приложение, и в вашем приложении был запрос на снятие десяти фунтов (да, я англичанин;)) со счета. Таким образом, вам необходимо прочитать текущий счет в локальной переменной, вычесть вывод средств и записать остаток обратно в память.
Однако, что если другой, параллельный запрос произойдет между вами, читающим значение, и вы записываете его? Существует вероятность того, что результат этого запроса будет полностью перезаписан первым, а баланс аккаунта будет неправильным.
Test-and-set помогает нам решить эту проблему, проверив, что значение, которое вы перезаписываете, соответствует ожидаемому. В этом случае вы можете проверить, что баланс был исходное значение, которое вы прочитали. Поскольку он атомарный, он не прерывается, поэтому никто не может вытащить коврик из-под вас между чтением и записью.
Еще один способ решить эту проблему - снять блокировку с ячейки памяти. К сожалению, очень трудно получить правильные блокировки, трудно их рассуждать, они имеют проблемы с масштабируемостью и плохо работают в условиях сбоев, поэтому они не являются идеальным (но определенно практичным) решением. Подходы «тест-и-набор» составляют основу некоторых программных транзакционных запоминающих устройств, которые оптимистично позволяют выполнять каждую транзакцию одновременно, за счет откатывания их всех обратно, если они конфликтуют.