Reputation: 1957
I tried an interview question with static
functions and non static functions as synchronized
and one function was non synchronized. As in below code:
public class Resource {
public static synchronized void m1() throws InterruptedException {
System.out.println("Entering m1 method");
Thread.sleep(10000);
System.out.println("Leaving m1 method");
System.out.println();
}
public synchronized void m2() throws InterruptedException {
System.out.println("Entering m2 method");
Thread.sleep(2000);
System.out.println("Leaving m2 method");
System.out.println();
}
public void m3() throws InterruptedException {
System.out.println("Entering m3 method");
Thread.sleep(2000);
System.out.println("Leaving m3 method");
System.out.println();
}
public synchronized void m4() throws InterruptedException {
System.out.println("Entering m4 method");
Thread.sleep(2000);
System.out.println("Leaving m4 method");
System.out.println();
}
}
public class ThreadDemo {
public static void main(String[] args) {
final Resource resource = new Resource();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
try {
resource.m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
resource.m2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
resource.m3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
try {
resource.m4();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Here four threads are created.
It's output is:
Entering m1 method
Entering m3 method
Entering m2 method
Leaving m3 method
Leaving m2 method
Entering m4 method
Leaving m4 method
Leaving m1 method
My question is:
1) static synchronized method make class level lock. Here what is the meaning of class level locking? If one thread has taken lock and class level lock is occupied then why thread T2 and T3 starts execution?
2) T4 is waiting to complete T2. Although synchronization is applied on two different methods, then why T4 has to wait? If object level lock is working in T2, T4 then in above point why class level locking is not working?
Upvotes: 0
Views: 940
Reputation: 38910
Regarding your queries:
1) static synchronized method make class level lock. Here what is the meaning of class level locking? If one thread has taken lock and class level lock is occupied then why thread T2 and T3 starts execution?
in case of static synchronized
methods, only one thread acquire lock on these methods among multiple instances of class. If you have two different instances : resource1
and resource2
for Resource
class, only one thread will succeed in getting lock on m1()
.
if resource1.m1()
method execution is in progress by one thread, other thread can't execute resource2.m1()
unless first thread finish the execution of m1()
.
Since method m3()
is non-synchronized method, any thread can invoke this method without wait and getting lock.
Since both m2()
and m4()
are synchronized, only one thread will succeed in getting lock on same object ( resource
in your example). Other thread has to wait until first thread completes the execution of synchrnozied
method and release object level lock.
2) T4 is waiting to complete T2. Although synchronization is applied on two different methods, then why T4 has to wait?If object level lock is working in T2, T4 then in above point why class level locking is not working?
Making these methods synchronized
has two effects:
First, it is not possible for two invocations of synchronized
methods on the same object to interleave. When one thread is executing a synchronized
method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.
The thread acquires the intrinsic lock for the Class
object associated with the class. Thus access to class's static
fields is controlled by a lock that's distinct from the lock for any instance of the class.
Upvotes: 0
Reputation: 3453
Static method synchronization is an equivalent for
public static void m1() {
synchronize (Resource.class) {
...
}
}
Non-static method synchronization is an equivalent for
public void m2() {
synchronize (this) {
...
}
}
Now if you will have a look where this
is using as monitor and where Resource.class
object is using as monitor everything should become clear.
A synchronized block in Java is synchronized on some object. All synchronized blocks synchronized on the same object can only have one thread executing inside them at the same time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
In your case there are two objects. So, this rule is applicable for each object, but not to both.
Upvotes: 2