According to my understanding, the following piece of code should result in a deadlock. The reason being, when thread t1 locks static object firstData, he has acquired a lock on the class. So, when he tries to lock another static object secondData, the request should block.
However, the program runs fine and prints *** Successfully acquired both the locks
What is it about locking static objects that im missing here?
public class Deadlock {
public static void main(String[] args) {
Thread t1 = new Thread(new DeadlockRunnable());
t1.start();
}
}
class DeadlockRunnable implements Runnable {
static Object firstData = new Object();
static Object secondData = new Object();
public void run() {
synchronized(firstData) {
synchronized(secondData) {
System.out.println("*** Successfully acquired both the locks");
}
}
}
}
For all those who answered that the locks are on object, instead of class, please take a look at this
It is used if you want to protect static data. If a thread wants to execute a static synchronized method, then the thread requires a class level lock. Once a thread got the class level lock, then it is allowed to execute any static synchronized method of that class.
As a rule of thumb, you want the lock-object to have the same static -ness than the operated-on value. So if you manipulate non-static values only, you'll want a non-static lock object. If you manipulate static values only, you'll want a static lock object.
The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created.
A static member class or interface is defined as a static member of a containing class, making it analogous to the class fields and methods that are also declared static. Like a class method, a static member class is not associated with any instance of the containing class (i.e., there is no this object).
Firstly, you have a mistake here:
The reason being, when thread t1 locks static object firstData, he has acquired a lock on the class.
Locking a static object locks only that object, not the class. You are locking two separate objects.
The question you refered to is about synchronized methods not synchronized statements. These two related constructs work in slightly different ways.
Secondly, even if you were locking on the same object, your code would still not deadlock (ideone). Intrinsic locks are reentrant. This means that a thread does not deadlock itself if it tries to take the same lock twice.
Reentrant Synchronization
Recall that a thread cannot acquire a lock owned by another thread. But a thread can acquire a lock that it already owns. Allowing a thread to acquire the same lock more than once enables reentrant synchronization. This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock. Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block.
Source
"when thread t1 locks static object firstData, he has acquired a lock on the class"
Not sure why you think so. t1 acquires a lock on firstData, not on the containing class. There is no possible deadlock in your code as it is.
EDIT
Following your comment, the link is about the difference between those 2 declarations:
public synchronized method() // lock on the instance (this)
public static synchronized method() // lock on the class (Myclass.class)
But there is no link with deadlocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With