Предупреждение: Если вы прочитаете комментарии, вы поймете, что мой ответ неверен:)
В вашем коде возможен тупик .
Представьте себе следующий случай, для ясности я использовал однопотоковый подход, но его должно быть легко преобразовать в многопоточность с помощью сна:
// We create some actions...
object locker = new object();
Action action1 = () => {
lock (locker)
{
System.Threading.Monitor.Wait(locker);
Console.WriteLine("This is action1");
}
};
Action action2 = () => {
lock (locker)
{
System.Threading.Monitor.Wait(locker);
Console.WriteLine("This is action2");
}
};
// ... (stuff happens, etc.)
// Imagine both actions were running
// and there's 0 items in the queue
// And now the producer kicks in...
lock (locker)
{
// This would add a job to the queue
Console.WriteLine("Pulse now!");
System.Threading.Monitor.Pulse(locker);
}
// ... (more stuff)
// and the actions finish now!
Console.WriteLine("Consume action!");
action1(); // Oops... they're locked...
action2();
Пожалуйста, дайте мне знать, если это не имеет никакого смысла.
Если это подтвердится, тогда ответ на ваш вопрос: «Нет, это не безопасно»;)
Надеюсь, это поможет.