Вопрос озадачен, и ответы до сих пор не совсем ясны.Позвольте мне перефразировать вопрос на несколько вопросов:
(1) Гарантирует ли оператор блокировки, что в теле оператора блокировки одновременно находится не более одного потока?
Нет .Например:
static readonly object lock1 = new object();
static readonly object lock2 = new object();
static int counter = 0;
static object M()
{
int c = Interlocked.Increment(ref counter);
return c % 2 == 0 ? lock1 : lock2;
}
...
lock(M()) { Critical(); }
Возможно, чтобы два потока одновременно находились в теле оператора блокировки, поскольку оператор блокировки блокирует два разных объекта.Поток Alpha может вызвать M () и получить lock1, а затем поток Beta может вызвать M () и получить lock2.
(2) Предполагая, что мой оператор блокировки всегда блокируется на одном и том же объекте, гарантирует ли оператор блокировки, что в теле тела одновременно находится не более одного «активного» потока?
Да.Если у вас есть:
static readonly object lock1 = new object();
...
lock(lock1) { Critical(); }
, тогда нить Альфа может взять блокировку, а бета нити будет блокировать до тех пор, пока блокировка не будет доступна, прежде чем войти в тело замка.
(3) Предполагая, что у меня есть два оператора блокировки, и оба оператора блокировки каждый раз блокируют один и тот же объект, оператор блокировки гарантирует, что не более одного «активного» потока находится в теле любой блокировки одновременно?
Да.Если у вас есть:
static readonly object lock1 = new object();
...
static void X()
{
lock(lock1) { CriticalX(); }
}
static void Y()
{
lock(lock1) { CriticalY(); }
}
, то, если нить Альфа находится в X и берет блокировку, а бета нити находится в Y, тогда бета нити будет блокировать до тех пор, пока блокировка не будет доступна до вводатело замка.
(4) Почему вы помещаете «активный» в «кавычки»?
Чтобы обратить внимание на тот факт, что это возможно для ожидание нить будет в корпусе замка.Вы можете использовать метод Monitor.Wait
, чтобы «приостановить» поток, находящийся в теле блокировки, и позволить заблокированному потоку стать активным и войти в это тело блокировки (или другое тело блокировки, которое блокирует тот же объект).Ожидающая нить будет оставаться в состоянии «ожидания» до тех пор, пока не произойдет импульс.Через некоторое время после импульса он снова присоединяется к очереди «готовности» и блокирует , пока в блокировке не останется «активный» поток.Затем он возобновляется в том месте, где остановился.