There are two common situations.
Two threads which attempt to acquire a series of locks in different orders can end up each holding a lock which the other is waiting for.
Code which attempts to acquire a lock it already holds (usually due to recursion). For this you should consider switching using java.util.concurrent.Lock. the ReentrantLock implementation solves this problem elegantly.