How to Solve Deadlock using Threads in Java?
If two threads are waiting for each other forever such type of infinite waiting is called deadlock in java. Synchronized keyword is the only reason for deadlock situation hence while using synchronized keyword we have to take special care. There is no resolution technique for deadlock, but several prevention techniques are available.
Implementation: Deadlock occurs
Example 1:
Tóm Tắt
Java
import
java.io.*;
import
java.util.*;
class
A {
public
synchronized
void
last()
{
System.out.println(
"Inside A, last() method"
);
}
public
synchronized
void
d1(B b)
{
System.out.println(
"Thread1 start execution of d1() method"
);
try
{
Thread.sleep(
2000
);
}
catch
(InterruptedException e) {
System.out.println(e);
}
System.out.println(
"Thread trying to call B's last() method"
);
b.last();
}
}
class
B {
public
synchronized
void
last()
{
System.out.println(
"Inside B, last() method"
);
}
public
synchronized
void
d2(A a)
{
System.out.println(
"Thread2 start execution of d2() method"
);
try
{
Thread.sleep(
2000
);
}
catch
(InterruptedException e) {
System.out.println(e);
}
System.out.println(
"Thread2 trying to call A's last method"
);
a.last();
}
}
class
GFG
extends
Thread {
A a =
new
A();
B b =
new
B();
public
void
m1()
{
this
.start();
a.d1(b);
}
public
void
run()
{
b.d2(a);
}
public
static
void
main(String[] args)
{
GFG deadlock =
new
GFG();
deadlock.m1();
}
}
Output:
Output explanation:
Here the cursor is showing forever because the threads enter into the deadlock situation. In the above program if we removed at least one synchronized keyword then the program won’t enter into the deadlock situation. Hence, synchronized keyword is one of the major reason for deadlock situation. Due to this while using synchronized keyword we have to take special care.
We can avoid Deadlock situation in the following ways:
- Using Thread.join() Method: We can get a deadlock if two threads are waiting for each other to finish indefinitely using thread join. Then our thread has to wait for another thread to finish, it is always best to use Thread.join() method with the maximum time you want to wait for the thread to finish.
- Use Lock Ordering: We have to always assign a numeric value to each lock and before acquiring the lock with a higher numeric value we have to acquire the locks with a lower numeric value.
- Avoiding unnecessary Locks: We should use locks only for those members on which it is required, unnecessary use of locks leads to a deadlock situation. And it is recommended to use a lock-free data structure and If it is possible to keep your code free from locks. For example, instead of using synchronized ArrayList use the ConcurrentLinkedQueue.
Example 2: Deadlock is prevented
Java
import
java.io.*;
import
java.util.*;
class
A {
public
synchronized
void
last()
{
System.out.println(
"Inside A, last() method"
);
}
public
synchronized
void
d1(B b)
{
System.out.println(
"Thread1 start execution of d1() method"
);
try
{
Thread.sleep(
2000
);
}
catch
(InterruptedException e) {
System.out.println(e);
}
System.out.println(
"Thread trying to call B's last() method"
);
b.last();
}
}
class
B {
public
void
last()
{
System.out.println(
"Inside B, last() method"
);
}
public
void
d2(A a)
{
System.out.println(
"Thread2 start execution of d2() method"
);
try
{
Thread.sleep(
2000
);
}
catch
(InterruptedException e) {
System.out.println(e);
}
System.out.println(
"Thread2 trying to call A's last method"
);
a.last();
}
}
class
GFG
extends
Thread {
A a =
new
A();
B b =
new
B();
public
void
m1()
{
this
.start();
a.d1(b);
}
public
void
run()
{
b.d2(a);
}
public
static
void
main(String[] args)
{
GFG deadlock =
new
GFG();
deadlock.m1();
}
}
Output:
My Personal Notes
arrow_drop_up