Deadlock in Java Multithreading

if two threads locks two resources and each attempt to access other thread resources, no one receives the resources. Both threads wait forever for resources. That’s called DeadLock. To get out of this situation, the Java process has to be killed.



DeadLock using two thread class

In the example below, Two threads are created using Two thread classes, MyThreadA and MyThreadB.
MyThreadA class locks the resource “resource1”.
MyThreadB class locks the resource “resource2”.
MyThreadA class attempts to access “resource2” and MyThreadB class attempts to access “resource1”.
Since both resources are locked, no one gets the resource.
This program will wait forever.

MyThreadA.java

package com.yawintutor;

public class MyThreadA extends Thread {
	public String resource1;
	public String resource2;

	public MyThreadA(String resource1, String resource2) {
		this.resource1 = resource1;
		this.resource2 = resource2;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " resource1 - waiting to locking");
		synchronized (resource1) {
			System.out.println("Thread name : " + getName() + " resource1 - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " resource2 - waiting to locking");
			synchronized (resource2) {
				System.out.println("Thread name : " + getName() + " resource2 - locked");
			}
		}
	}

}

MyThreadB.java

package com.yawintutor;

public class MyThreadB extends Thread {
	public String resource1;
	public String resource2;

	public MyThreadB(String resource1, String resource2) {
		this.resource1 = resource1;
		this.resource2 = resource2;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " resource2 - waiting to locking");
		synchronized (resource2) {
			System.out.println("Thread name : " + getName() + " resource2 - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " resource1 - waiting to locking");
			synchronized (resource1) {
				System.out.println("Thread name : " + getName() + " resource1 - locked");
			}
		}
	}

}

ThreadMain.java

package com.yawintutor;

public class ThreadMain {
	public static void main(String[] args) throws Exception {
		String resource1 = new String("resource1");
		String resource2 = new String("resource2");

		MyThreadA thread1 = new MyThreadA(resource1, resource2);
		thread1.setName("THREAD 1");
		thread1.start();

		MyThreadB thread2 = new MyThreadB(resource1, resource2);
		thread2.setName("THREAD 2");
		thread2.start();

	}
}

Output

Thread name : THREAD 1 resource1 - waiting to locking
Thread name : THREAD 1 resource1 - locked
Thread name : THREAD 2 resource2 - waiting to locking
Thread name : THREAD 2 resource2 - locked
Thread name : THREAD 1 resource2 - waiting to locking
Thread name : THREAD 2 resource1 - waiting to locking


DeadLock using three thread class

Three threads are involved to create a deadlock in this example. Three thread classes are MyThreadA, MyThreadB and MyThreadC.
MyThreadA class locks the resource “resource1”.
MyThreadB class locks the resource “resource2”.
MyThreadC class locks the resource “resource3”.
MyThreadA class attempts to access “resource2”, MyThreadB class attempts to access “resource3” and MyThreadC class attempts to access “resource1”.
Since all three resources are locked, no one receives the resource.
This program is going to wait forever.

MyThreadA.java

package com.yawintutor;

public class MyThreadA extends Thread {
	public String resource1;
	public String resource2;

	public MyThreadA(String resource1, String resource2) {
		this.resource1 = resource1;
		this.resource2 = resource2;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " resource1 - waiting to locking");
		synchronized (resource1) {
			System.out.println("Thread name : " + getName() + " resource1 - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " resource2 - waiting to locking");
			synchronized (resource2) {
				System.out.println("Thread name : " + getName() + " resource2 - locked");
			}
		}
	}

}

MyThreadB.java

package com.yawintutor;

public class MyThreadB extends Thread {
	public String resource2;
	public String resource3;

	public MyThreadB(String resource2, String resource3) {
		this.resource2 = resource2;
		this.resource3 = resource3;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " resource2 - waiting to locking");
		synchronized (resource2) {
			System.out.println("Thread name : " + getName() + " resource2 - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " resource3 - waiting to locking");
			synchronized (resource3) {
				System.out.println("Thread name : " + getName() + " resource3 - locked");
			}
		}
	}

}

MythreadC.java

package com.yawintutor;

public class MyThreadC extends Thread {
	public String resource1;
	public String resource3;

	public MyThreadC(String resource1, String resource3) {
		this.resource1 = resource1;
		this.resource3 = resource3;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " resource3 - waiting to locking");
		synchronized (resource3) {
			System.out.println("Thread name : " + getName() + " resource3 - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " resource1 - waiting to locking");
			synchronized (resource1) {
				System.out.println("Thread name : " + getName() + " resource1 - locked");
			}
		}
	}

}

ThreadMain.java

package com.yawintutor;

public class ThreadMain {
	public static void main(String[] args) throws Exception {
		String resource1 = new String("resource1");
		String resource2 = new String("resource2");
		String resource3 = new String("resource3");

		MyThreadA thread1 = new MyThreadA(resource1, resource2);
		thread1.setName("THREAD 1");
		thread1.start();

		MyThreadB thread2 = new MyThreadB(resource2, resource3);
		thread2.setName("THREAD 2");
		thread2.start();

		MyThreadC thread3 = new MyThreadC(resource1, resource3);
		thread3.setName("THREAD 3");
		thread3.start();
	}
}

Output

Thread name : THREAD 1 resource1 - waiting to locking
Thread name : THREAD 1 resource1 - locked
Thread name : THREAD 3 resource3 - waiting to locking
Thread name : THREAD 3 resource3 - locked
Thread name : THREAD 2 resource2 - waiting to locking
Thread name : THREAD 2 resource2 - locked
Thread name : THREAD 3 resource1 - waiting to locking
Thread name : THREAD 2 resource3 - waiting to locking
Thread name : THREAD 1 resource2 - waiting to locking


DeadLock using a thread class

Two threads are created using a Thread class and resources are send dynamically that causes deadlock.

MyThread.java

package com.yawintutor;

public class MyThread extends Thread {
	public String resource1;
	public String resource2;

	public MyThread(String resource1, String resource2) {
		this.resource1 = resource1;
		this.resource2 = resource2;
	}

	public void run() {
		System.out.println("Thread name : " + getName() + " " + resource1 + " - waiting to locking");
		synchronized (resource1) {
			System.out.println("Thread name : " + getName() + " " + resource1 + " - locked");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println("Thread name : " + getName() + " " + resource2 + " - waiting to locking");
			synchronized (resource2) {
				System.out.println("Thread name : " + getName() + " " + resource2 + " - locked");
			}
		}
	}
}

ThreadMain.java

package com.yawintutor;

public class ThreadMain {
	public static void main(String[] args) throws Exception {
		String resource1 = new String("resource1");
		String resource2 = new String("resource2");

		MyThread thread1 = new MyThread(resource1, resource2);
		thread1.setName("THREAD 1");
		thread1.start();

		MyThread thread2 = new MyThread(resource2, resource1);
		thread2.setName("THREAD 2");
		thread2.start();

	}
}

Output

Thread name : THREAD 1 resource1 - waiting to locking
Thread name : THREAD 2 resource2 - waiting to locking
Thread name : THREAD 1 resource1 - locked
Thread name : THREAD 2 resource2 - locked
Thread name : THREAD 1 resource2 - waiting to locking
Thread name : THREAD 2 resource1 - waiting to locking



Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *