Я вижу, что для использования объектов, которые не являются потокобезопасными, мы заключаем код в блокировку следующим образом:
private static readonly Object obj = new Object();
lock (obj)
{
// thread unsafe code
}
Так что же происходит, когда несколько потоков обращаются к одному и тому же коду (предположим, что он выполняется в веб-приложении ASP.NET). Они в очереди? Если так, то как долго они будут ждать?
Какое влияние на производительность оказывает использование блокировок?
Ответы:
Это
lock
заявление переведено C # 3.0 на следующее:В C # 4.0 это изменилось, и теперь оно генерируется следующим образом:
Вы можете найти больше информации о том,
Monitor.Enter
что здесь . Чтобы процитировать MSDN:Monitor.Enter
Метод будет ждать бесконечно; это не будет время ожидания.источник
obj
без всякой блокировки системы.lock
-statement и Monitor: чтобы вы могли выполнять операцию в одном потоке, не беспокоясь о том, что другой поток его испортит.Это проще, чем вы думаете.
Согласно Microsoft :
lock
ключевое слово гарантирует, что один поток не входит в критический раздел кода, в то время как другой поток находится в критическом разделе. Если другой поток пытается ввести заблокированный код, он будет ждать блокировки до тех пор, пока объект не будет освобожден.lock
Ключевое слово вызываетEnter
в начале блока иExit
в конце блока.lock
Ключевое слово на самом деле обрабатываетMonitor
класс в конце.Например:
В приведенном выше коде сначала поток входит в критическую секцию, а затем блокируется
obj
. Когда другой поток пытается войти, он также пытается заблокироватьobj
, который уже заблокирован первым потоком. Второму потоку придется ждать первого потока, чтобы освободитьobj
. Когда первый поток удаляется, другой поток блокируетсяobj
и входит в критическую секцию.источник
Нет, они не стоят в очереди, они спят
Оператор блокировки формы
где x является выражением ссылочного типа, точно эквивалентно
Вам просто нужно знать, что они ждут друг друга, и только один поток войдет в блок блокировки, остальные будут ждать ...
Монитор полностью написан на .net, поэтому он достаточно быстрый, также смотрите класс Monitor с отражателем для более подробной информации.
источник
lock
утверждения, немного изменился в C # 4: blogs.msdn.com/b/ericlippert/archive/2009/03/06/…Блокировки блокируют выполнение другими потоками кода, содержащегося в блоке блокировки. Потоки должны будут ждать, пока нить в блоке блокировки не завершится и блокировка не будет снята. Это оказывает негативное влияние на производительность в многопоточной среде. Если вам нужно это сделать, убедитесь, что код в блоке блокировки может обрабатываться очень быстро. Вы должны избегать дорогостоящих действий, таких как доступ к базе данных и т. Д.
источник
Влияние на производительность зависит от способа блокировки. Вы можете найти хороший список оптимизаций здесь: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
По сути, вы должны пытаться блокировать как можно меньше, так как это переводит ваш код ожидания в спящий режим. Если у вас есть некоторые тяжелые вычисления или длительный код (например, загрузка файла) в блокировке, это приводит к огромной потере производительности.
источник
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]. Самая большая опасность состоит в том, что если требования развиваются сверх того, что могут обрабатывать такие методы, может быть сложно адаптировать код для этого.Часть в операторе блокировки может быть выполнена только одним потоком, поэтому все остальные потоки будут бесконечно ждать, пока поток, удерживающий блокировку, завершится. Это может привести к так называемой тупиковой ситуации.
источник
lock
Заявление переводятся на призывы кEnter
иExit
методамMonitor
.lock
Заявление будет ждать неопределенное время для блокировки объекта должен быть освобожден.источник
Блокировка на самом деле скрыта классом Monitor .
источник