Распространённые ситуации неправильного использования: чтобы предотвратить дублирование оплаты заказов, вызванное случайными нажатием кнопки оплаты пользователями несколько раз, мы используем блокировку (номер заказа), чтобы гарантировать, что операцию выполняет только один поток.
Эта идея хороша, по крайней мере лучше, чем блокировка (частный статический объект для классов обработки), потому что эффект блокировки номера ордера заключается в блокировке только операции текущего порядка 1, а если блокировать статическую переменную, то есть блокировать все приказы, то есть все приказы будут поставлены в очередь, что, очевидно, неразумно.
Так может ли метод замка (номер заказа), упомянутый в начале этой статьи, достичь желаемого эффекта? Давайте сначала восстановим сценарий использования.
Если игнорировать пользовательскую информацию и другие валидации, код выглядит примерно так:
Для ключевого слова lock MSDN включает информацию, которую можно найти на Baidu, и, похоже, рекомендуется не использовать lock(string), причина та же. Следующий отрывок взят из рекомендаций MSDN по замковым струнам:
Проблема с блокировкой («myLock») возникает потому, что любой другой код, использующий ту же строку в процессе, будет иметь тот же блокировочный блок. Это предложение скрывает огромный механизм, то есть «та же нить».
Что такое «одна и та же нить»? См. код:
Str1 и str2 — это одна и та же строка, описанная выше? Ответ — ДА.
Смотрите ещё раз:
Str1 и str2 выше всё ещё одинаковые струны? Мой ответ – нет.
Ладно, вернёмся к вопросу оплаты заказа. В нашем коде, lock(orderNumber), когда пользователь случайно нажимает ещё несколько раз после свайпа, вводится ли orderNumber в одну и ту же строку каждый раз? Мой ответ – нет. То есть
Код, который обрабатывает приведённый выше приказ, фактически не является блокировкой.
На самом деле существует два типа сравнений строк, см. код:
Первая строка вышеуказанного кода выводит True, а вторая строка — False. Полагаю, вы понимаете, что MSDN имеет в виду под «одной и той же строкой» без моих объяснений.
Лучшее решение
Решения для оптимальных блокирующих строк:
Демо-код:
На сайте иногда используется глобальная переменная, которая при одновременном доступе нескольких пользователей может показаться ненормальной, в этот момент мы устанавливаем глобальную блокировку, но недостаток в том, что все доступы будут ждать по очереди.
В некоторых случаях, например, один и тот же пользователь может оставить комментарий только один раз в течение 15 секунд, а при использовании глобального блокировки функция комментариев будет очень медленно обрабатываться при резком росте числа пользователей, что сильно влияет на пользовательский опыт.
В это время,Мы можем установить блокировку для каждого пользователя отдельно, lock(string){...}, и имя замка можно определить следующим образом:Имя метода + идентификатор пользователяТаким образом, у каждого пользователя есть независимая блокировка, и при оценке интервала комментариев это не влияет на комментарии других пользователей.
(Конец)
|