《Java concurrency in practice》一书说道，
When a thread requests a lock that is already held by another thread, the requesting thread blocks.
But because intrinsic locks are reentrant, if a thread tries to acquire a lock that it already holds, the request succeeds.
Reentrancy means that locks are acquired on a per-thread rather than per-invocation basis.
Reentrancy is implemented by associating with each lock an acquisition count and an owning thread.
When the count is zero, the lock is considered unheld. When a thread acquires a previously unheld lock,
the JVM records the owner and sets the acquisition count to one. If that same thread acquires the lock again,
the count is incremented, and when the owning thread exits the synchronized block, the count is decremented.
When the count reaches zero, the lock is released.