Start here. This is the direct spoken answer to practice first.
Why this question matters
Deadlocks are structural cycles, not merely slow locks. A reliable answer identifies the ownership graph and removes the cycle instead of adding arbitrary delays until reproduction becomes harder.
I would capture thread dumps or runtime traces while the process is stuck and identify which thread owns each lock and which lock it is waiting for. In the transfer example, thread A may lock account 1 then wait for account 2 while thread B locks account 2 then waits for account 1. I would make every transfer acquire account locks in one stable order, such as by account ID, regardless of transfer direction. I would also keep the critical section short and avoid I/O or blocking waits while holding either lock.