Если поток уже удерживает блокировку, то он может снова «взять эту блокировку» без проблем.
Что касается почему , (и почему это хорошоидея), рассмотрим следующую ситуацию, где у нас есть определенный порядок блокировки в другом месте в программе a -> b:
void f()
{
lock(a)
{ /* do stuff inside a */ }
}
void doStuff()
{
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
Ой, мы просто нарушили порядок блокировки и имеем потенциальный тупик в наших руках.
Мы на самом деле должны быть в состоянии сделать следующее:
function doStuff()
{
lock(a)
lock(b)
{
//do stuff inside b, that involves leaving b in an inconsistent state
f();
//do more stuff inside b so that its consistent again
}
}
Так что наш порядок блокировки поддерживается, без самоблокировки при вызове f()
.