Static Lock
If the locked-on object is in a static field, then all instances of that particular Class will share that lock. It means that if one object created from that class is accessing that static
lock, another object created from that class can not access that lock.
Non-static Lock
If the class has a lock that is non-static, then each instance will have its own lock, so only calls of the method on the same object will lock each other.
As an example when you use a static lock object:
- thread 1 calls
obj01.doSomething()
- thread 2 calls
obj01.doSomething()
, will have to wait for thread 1 to finish
- thread 3 calls
obj02.doSomething()
, will also have to wait for thread 1 (and probably 2) to finish.
When you use a non-static lock object:
- thread 1 calls
obj01.doSomething()
- thread 2 calls
obj01.doSomething()
, will have to wait for thread 1 to finish
- thread 3 calls
obj02.doSomething()
, it can just continue, not minding threads 1 and 2, because this is a new object and it does not depend on the class.
non-static locks are basically object-level Locks. static locks are class level Locks
Object Level Lock
Every object in Java has a unique lock. If a thread wants to execute a synchronized method on a given object, first it has to get a lock of that object. Once the thread got the lock then it is allowed to execute any synchronized method on that object. Once method execution completes automatically thread releases the lock.
public class Example implements Runnable {
@Override
public void run() {
objectLock();
}
public void objectLock() {
System.out.println(Thread.currentThread().getName());
synchronized(this) {
System.out.println("Synchronized block " + Thread.currentThread().getName());
System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Example test1 = new Example();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test1);
Example test2 = new Example();
Thread t3 = new Thread(test2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
The output will be,
t1
t3
Synchronized block t1
t2
Synchronized block t1 end
Synchronized block t3
Synchronized block t2
Synchronized block t3 end
Synchronized block t2 end
Class Level Locks
Every class in Java has a unique lock which is nothing but a class level lock. 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. Once method execution completes automatically thread releases the lock.
public class Example implements Runnable {
@Override
public void run() {
classLock();
}
public static void classLock() {
System.out.println(Thread.currentThread().getName());
synchronized(Example.class) {
System.out.println("Synchronized block " + Thread.currentThread().getName());
System.out.println("Synchronized block " + Thread.currentThread().getName() + " end");
}
}
public static void main(String[] args) {
Example test1 = new Example();
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test1);
Example test2 = new Example();
Thread t3 = new Thread(test2);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.start();
t2.start();
t3.start();
}
}
The output will look like below,
t1
t3
t2
Synchronized block t1
Synchronized block t1 end
Synchronized block t2
Synchronized block t2 end
Synchronized block t3
Synchronized block t3 end
Current Scenario
In here you have two methods and if one method is accessed using one lock and the other is using another lock, with your implementation you can have two objects using each other methods but never the same method.
obj01.method01();
obj02.method02();
this is possible,but not this
obj01.method01();
obj02.method01();
you obj02
has to wait till obj01
finish the method.