Deadlock occurs because:
Mutual exclusion: There is a resource which can be accessed only by one thread at any point in time.
Resource holding: While having locked one resource, the thread tries to acquire another lock on some other exclusive resource.
No preemption: there is any mechanism, which frees the resource if one thread holds the lock for a specific period of time.
Circular wait: During runtime a constellation occurs in which two (or more) threads are each waiting on the other thread to free a resource that it has locked.
In order to prevent deadlocks one (or more) of the requirements for a deadlock has to be eliminated:
Mutual exclusion: In some situation it is possible to prevent mutual exclusion by using optimistic locking.
Resource holding: A thread may release all its exclusive locks, when it does not succeed in obtaining all exclusive locks.
No preemption: Using a time-out for an exclusive lock frees the lock after a given amount of time.
Circular wait: When all exclusive locks are obtained by all threads in the same sequence, no circular wait occurs.