What is a Deadlock?
Deadlock is a situation that arises in case of two or more threads blocking each other’s resources while waiting for one at the same time. This condition emerges when various threads require the same resources which are acquired by one another.
Now, Before moving further into deadlocks, you need to require the basic understanding of the Java language. As currently Java is being used in various applications (from standalone to complex machine learning based) and mobile application. It has created numerous opportunities for freshers and experts in various fields such as mobile app development, gaming, robotics, etc. One can go through the Java Certification training courses, videos, blogs, and various other resources to explore development from a ground level. Thus, they can deliver more effective results in their respected field.
In java multithreading program, situations like deadlock are very common since synchronized keywords block the running thread when it waits for the lock.
In an operating system, a process handles resources in the following manner:
It requests for a resource
It uses that resource once acquired
It releases that resource
It can be easily understood with a real-world example of two cars running on the same single track. They both can’t move further as they are in front of one another.
The same situation occurs in case of thread two or more processes keeps resources and wait for each other’s resources.
Example :
The figure below demonstrates that thread A is holding resource 1 and demands for the resource 2.Similarly, thread B keeps resource 2, and it requires resource 1.
Both of these threads are making the deadlock scenario here.
TestDeadlockExample1.java
- public class TestDeadlockExample1 {
- public static void main(String[] args) {
- final String resource1 = "ratan jaiswal";
- final String resource2 = "vimal jaiswal";
- // t1 tries to lock resource1 then resource2
- Thread t1 = new Thread() {
- public void run() {
- synchronized (resource1) {
- System.out.println("Thread 1: locked resource 1");
- try { Thread.sleep(100);} catch (Exception e) {}
- synchronized (resource2) {
- System.out.println("Thread 1: locked resource 2");
- }
- }
- }
- };
- // t2 tries to lock resource2 then resource1
- Thread t2 = new Thread() {
- public void run() {
- synchronized (resource2) {
- System.out.println("Thread 2: locked resource 2");
- try { Thread.sleep(100);} catch (Exception e) {}
- synchronized (resource1) {
- System.out.println("Thread 2: locked resource 1");
- }
- }
- }
- };
- t1.start();
- t2.start();
- }
- }
public class TestDeadlockExample1 { public static void main(String[] args) { final String resource1 = "ratan jaiswal"; final String resource2 = "vimal jaiswal"; // t1 tries to lock resource1 then resource2 Thread t1 = new Thread() { public void run() { synchronized (resource1) { System.out.println("Thread 1: locked resource 1"); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource2) { System.out.println("Thread 1: locked resource 2"); } } } }; // t2 tries to lock resource2 then resource1 Thread t2 = new Thread() { public void run() { synchronized (resource2) { System.out.println("Thread 2: locked resource 2"); try { Thread.sleep(100);} catch (Exception e) {} synchronized (resource1) { System.out.println("Thread 2: locked resource 1"); } } } }; t1.start(); t2.start(); } }
On executing this code, it will create a deadlock situation as discussed in the above scenario.
Why deadlock occurs ?
Below is the necessary condition for a deadlock occurrence:
Mutual Exclusion: In this case, one or more than a resource is kept non-sharable. Thus, only one thread can use at a time.
No Preemption: A resource can’t be used until it is released by the process using it at that time.
Circular Wait: Group of processes waiting for one another’s resources in a circular form.
Hold and Wait: A process is using one resource keeping lock at it, while at the same time waiting for other resources.
How to Handle the Deadlock condition ?
Avoid Deadlock:
The first method is not to allow your program to enter into a deadlock situation.
Identification and Recovery: Once you encounter a deadlock, perform preemption to handle it smoothly.
Ignore all: If the deadlock is very common then allow it to happen. Reboot your program or system.
Resolution to deadlock:
I think this situation can be handled by recognizing the key problems.
In above-discussed case, the way both the resources are getting accessed is the main reason behind deadlock.
So, it requires just a little rearrangement of the resource while accessing them.
- // first thread
- //thread communication
- class Customer{
- int amount=10000;
- synchronized void withdraw(int amount){
- System.out.println("Going To Withdraw...");
- if(this.amount<amount){
- System.out.println("Less Balance; Waiting For Deposit...");
- try{wait();}catch(Exception e){}
- }
- this.amount-=amount;
- System.out.println("Yeah! Withdraw Completed...");
- }
- synchronized void deposit(int amount){
- System.out.println("Going To Deposit...");
- this.amount+=amount;
- System.out.println("Deposit Completed... ");
- notify();
- }
- }
- class Test{
- public static void main(String args[]){
- final Customer c=new Customer();
- new Thread(){
- public void run(){c.withdraw(15000);}
- }.start();
- new Thread(){
- public void run(){c.deposit(10000);}
- }.start();
- }}
// first thread //thread communication class Customer{ int amount=10000; synchronized void withdraw(int amount){ System.out.println("Going To Withdraw..."); if(this.amount<amount){ System.out.println("Less Balance; Waiting For Deposit..."); try{wait();}catch(Exception e){} } this.amount-=amount; System.out.println("Yeah! Withdraw Completed..."); } synchronized void deposit(int amount){ System.out.println("Going To Deposit..."); this.amount+=amount; System.out.println("Deposit Completed... "); notify(); } } class Test{ public static void main(String args[]){ final Customer c=new Customer(); new Thread(){ public void run(){c.withdraw(15000);} }.start(); new Thread(){ public void run(){c.deposit(10000);} }.start(); }}
Again, execute this code, and you will see it running without any deadlock. Thus, you can
Is Static Variables or Static reference of a class are stored in either Heap area or Method Area?
First thing, static variables will never be a part of method, it will be a part of class always.
So only we cant declare any static variables inside a method but we can access them inside a method.
All static variables will be stored in separate segment inside Heap area only.
Dear Kb,
I go through your blog quite often. Concepts explained out here are very lucid.
Much appreciated .
Thanks a lot Vivek !!
Sure will keep doing my best.
Happy Learning !
Hey Karibasappa,
You are one amazing talented person.
Great examples.
Good job.
Keep it up.
Thank you !!
The blog is very helpful. Thanks a lot for sharing! Also the “Inheritance in interface” page is not opening. Can you please fix that?
Hi Pravakar,
Thank you !!
I am looking into it, will resolve it soon.
Good to inform you that, inheritance in interface link issue is working now !!