자, 이제 다음 내용을 봅시다. 다음과 같이 잠그면 어떻게 될까요? A, B, C가 이미 순서대로 잠긴 상태에서 B와 A를 또 잠그는 것입니다. 즉, 재귀 잠금입니다.
A → B → C → B → A
lock(A) // ➊ lock(B) // ➋ lock(C) // ➌ lock(B) // ➍ lock(A) // ➎ unlock(C) // ➏ unlock(B) // ➐ unlock(A) // ➑
➌~➎는 잠금 순서 그래프와 거꾸로 가고 있습니다! 교착 상태일까요? 아닙니다. 이미 잠근 것에 대한 재귀 잠금은 잠금 순서 그래프와 상관없기 때문입니다. ➊~➌까지는 첫 잠금이고, 이때는 잠금 순서 그래프를 지켰습니다. ➍~➎는 이미 잠근 것을 또 잠그는 것이므로 잠금 순서 그래프를 무시해도 됩니다.
하지만 첫 잠금에서 순서를 어긴다면 교착 상태를 일으킵니다. 다음 코드를 봅시다.
A → C → B → C → A
lock(A) // ➊ lock(C) // ➋ lock(B) // ➌ lock(C) // ➍ lock(A) // ➎ unlock(C) // ➏ unlock(B) // ➐ unlock(A) // ➑