This is the story of two greedy threads. These two greedy threads wanted to get a resource whilst they were holding another. It is well known that when a thread holds a resource, some other thread may need that resource and should wait patiently inactive until the resource is freed. That works well among normal threads, but the greedy threads in this story they want to hold two or more resources for themselves.
Happens in this story that in at particular time, one of the greedy threads held a resource needed by another greedy thread that was already holding a resource needed by the first thread, what a mess!. Their greedness lead them to waiting forever as any of them would release their resource for letting the other complete.
This childist story is a real deal in multithreaded systems that share resources. This problem may come not only in bad designed systems but in systems with very high resource sharing. Even the better system design can´t avoid this situation as deadlocks can come not only between two threads, it can involve any number of resources and threads.
So, a deadlock can be defined as a circular dependency between tasks and resources.
There are four conditions that may cause a deadlock. The merely prescence of only one of them means deadlock may occur in the system. Theoretically, if all this conditions are avoided then we will have a deadlock free system (that, in my personal opinion, makes a very boring system and useless for the means of multithreading ).
A system that have at least one resource that can be simultaneously used only by one thread or by a limited number of threads.
All threads wait for more resources they need without freeing the resources they already have (remember greedy threads?).
When a resource is allocated by a thread, the RTOS can´t cancel this allocation. (the marine has more power than the captain)
If we represent some resource sharing by threads in a graph, we may identify a circular dependency in the graph.