I have two independent classes and both classes functions are calling each other. I have put the synchronization block on both classes functions but coverity is giving the error regarding LOCK_INVERSION and LOCK_ORDER or it might result in deadlock, not sure.
I am getting below error in coverity on my production code.
Acquiring lock 'lockname' conflicts with the lock order established elsewhere.
Sample example:
package multithreading;
public class Test1 implements Runnable {
private static Test1 instance = null;
public static synchronized Test1 getInstance() {
if (instance == null) {
instance = new Test1();
return instance;
} else {
return instance;
}
}
private Object lock = new Object();
public void sendUpdate() {
synchronized (lock) {
try {
Thread.sleep(3000l);
System.out.println(getClass().getSimpleName() + "sendUpdate");
Test2.getInstance().send();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sendUpdate1() {
synchronized (lock) {
try {
Thread.sleep(3000l);
System.out.println(getClass().getSimpleName() + "sendUpdate1");
Test2.getInstance().send();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread t = new Thread(Test1.getInstance());
t.start();
}
@Override
public void run() {
while (true) {
this.sendUpdate();
}
}
}
package multithreading;
public class Test2 implements Runnable {
private static Object object = new Object();
private static Test2 instance = null;
public static synchronized Test2 getInstance() {
if (instance == null) {
instance = new Test2();
return instance;
} else {
return instance;
}
}
public void send1() {
synchronized (object) {
try {
Thread.sleep(3000l);
System.out.println(getClass().getSimpleName() + "send1");
Test1.getInstance().sendUpdate();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void send() {
synchronized (object) {
try {
Thread.sleep(3000l);
System.out.println(getClass().getSimpleName() + "send");
Test1.getInstance().sendUpdate();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Thread t = new Thread(Test2.getInstance());
t.start();
}
@Override
public void run() {
while (true) {
Test2.getInstance().send1();
}
}
}
Analysis summary report:
------------------------
Files analyzed : 2 Total
Java (without build) : 2
Total LoC input to cov-analyze : 90
Functions analyzed : 15
Paths analyzed : 71
Time taken by analysis : 00:00:18
Defect occurrences found : 1 LOCK_INVERSION
I think this can lead to deadlock problem but would like to understand how to basically handle synchronization in two independent classes calling each other functions.
How can we maintain the lock order among two classes? Should I use the ENUM based shared lock but I am little bit worried about the performance or there is any other way to handle such scenario?