For understanding our first scenario we have to ride a car in a small Village where you have very narrow lanes. Adding to your pain you have buffaloes leading you. I hope you are enjoying the ride 🙂 .


After several rounds of heavy honking you get to overtake the buffaloes HURRAAYY!!, but WAIT.
You find yourself in a worse situation.
Guess what, you have another vehicle coming towards you from nowhere. Both the vehicles stopped. As you have a full army of buffaloes behind, you cannot move backwards and you simply wait until the other vehicle moves. Driver of the other vehicle looks in the mirror, to check what’s behind. He tries to move and soon realizes that he should stop as there are other vehicles honking. Left with no choice he simply waits for you.
And like that, you spend hours but could not move anywhere.Welcome to !!!DEADLOCK!!! .
If we take a close look, what exactly happened? There were two vehicles (concurrent threads) and two roads (resources)
(assuming your part of the road as a separate one). Each vehicle was occupying (locking) a road and waiting for the other road to be freed (lock released) which never happens.
In real world we can figure out other ways to escape the deadlock situation, but what happens to a computer in a deadlock state ? Any guesses ? It hangs. So as a result we have to kill one of the program to make sure the lock is released. But as a consequence we may lose the state of the program, which is a really bad thing to happen.
Now since we understand what is a deadlock lets take a look at a simple code snippet which will cause a deadlock :
Pseudo Code :
//Create resources
Resource resource1 = new Resource(“My first resource”);
Resource resource2 = new Resource(“My second resource);
//Create threads
Thread thread1 = new Thread(“My first thread”){
public void run(){ //Thread body
while(true){
synchronized(resource1){ //lock resource 1
synchronized(resource2) { // try locking resource 2
//do something;
}
}
}
}
};
Thread thread2 = new Thread(“My second thread”){
public void run(){
while(true){synchronized(resource2){ //lock resource 2
synchronized(resource1) { //try lock resource 1
//do something;
}
}
}
}
};
//Start both the threads.
thread1.start();
thread2.start();
Note: To further increase the deadlock chances we can add a sleep in one of threads inside the first synchronized block.
Above code results in a deadlock. Why ? Same case as the above car example.
Two threads, (playing with two resources) each acquiring a lock on a resource and trying to acquire lock on the other but fail to do so. Hence they go in an infinite wait.
Tips to avoid deadlock :
1) We should try to avoid acquiring locks on several resources at once. If required we should acquire locks in same order.
2) Using interruptible locks.
3) Do as little as you can after acquiring a lock.
4) Use advanced concurrency frameworks to gain more control. Refer Java concurrent package.
Hope this article was helpful. Thanks for visiting.
Cheers,
Kaivaly apte