If a thread T1 enters a method m1 by obtaining the class level lock, does this mean another thread T2 cannot run a different method m2 by obtaining the object level lock?
If a thread T1 enters a method m1 by obtaining the class level lock, does this mean another thread T2 cannot run a different method m2 by obtaining the object level lock?
Nope, both can execute concurrently. 1.When class level lock is applied on one method synchronized(SomeClass.class) and on other method object level lock is applied synchronized(this) then, both can execute at same time.
only when class level lock is applied on both methods then there is no concurrent execution.
Reason being: for class, jvm creates object for java.lang.Class, i.e. in short everything in java is object. So, when class level lock is applied on 2 methods, common lock is applied on class object and every object has single lock so, every thread waits, but when different instance is used to invoke the 2nd method and instance level lock is applied at that time, this object lock is applied which is different from class object lock and so concurrent execution is possible.
Instance Level Locking, Only single thread is allowed to execute at a time using instance level locking.
public class Refactor implements Runnable {
private Object obj;
public Refactor(Object obj)
{
this.obj = obj;
}
public void run() {
if (Thread.currentThread().getName().equalsIgnoreCase("Test1")) {
test1();
} else {
test2();
}
}
public void test1() {
synchronized (obj) {
System.out.println("Test1");
}
}
public synchronized void test2() {
synchronized (obj) {
System.out.println("Test2");
}
}
public static void main(String[] args) {
Object obj = new Object();
Thread t1 = new Thread(new Refactor(obj));
t1.setName("Test1");
t1.start();
Thread t2 = new Thread(new Refactor(obj));
t2.setName("Test2");
t2.start();
}
}
Class Level Locking, Only single thread is allowed to execute at a time using class level locking.
public class Refactor implements Runnable {
private Object obj;
public Refactor(Object obj)
{
this.obj = obj;
}
public void run() {
if (Thread.currentThread().getName().equalsIgnoreCase("Test1")) {
test1();
} else {
test2();
}
}
public static void test1() {
synchronized (Refactor.class) {
System.out.println("Test1");
}
}
public static synchronized void test2() {
synchronized (Refactor.class) {
System.out.println("Test2");
}
}
public static void main(String[] args) {
Object obj = new Object();
Thread t1 = new Thread(new Refactor(obj));
t1.setName("Test1");
t1.start();
Thread t2 = new Thread(new Refactor(obj));
t2.setName("Test2");
t2.start();
}
}