Object level vs class level lock- Java
When you use a static lock object:
- thread 1 calls
o1.foo() - thread 2 calls
o1.foo(), will have to wait for thread 1 to finish - thread 3 calls
o2.foo(), will also have to wait for thread 1 (and probably 2) to finish
When you use a non-static lock object:
- thread 1 calls
o1.foo() - thread 2 calls
o1.foo(), will have to wait for thread 1 to finish - thread 3 calls
o2.foo(), it can just continue, not minding thread 1 and 2
Example:
Object level lock is used to add synchronization to threads created from the same object. On the other hand, Class level lock is used to add synchronization to threads created from all objects of a class.
Let us see each one of these locking mechanism one by one:
Object Level locking
package com.example;public class Bar 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) { Bar b1 = new Bar(); Thread t1 = new Thread(b1); Thread t2 = new Thread(b1); Bar b2 = new Bar(); Thread t3 = new Thread(b2); t1.setName("t1"); t2.setName("t2"); t3.setName("t3"); t1.start(); t2.start(); t3.start(); }} |
Output:
t1
t3
t2
synchronized block t3
synchronized block t3 end
synchronized block t1
synchronized block t1 end
synchronized block t2
synchronized block t2 end
Note that the thread t3 will not block when threads t1 and t2 block. This is because the lock has been placed on “this” object and thread t3 has different “this” object than threads t1 or t2.
Class Level lock
The code in object level lock example is using this reference for locking. However we can replace it with a clazz object so that it becomes a class level lock. By using a Bar class level lock, all the threads created using any object of class Bar shall get blocked.
The source code with modified lock follows:
package com.example;public class Bar implements Runnable { @Override public void run() { objectLock(); } public void objectLock() { System.out.println(Thread.currentThread().getName()); synchronized(Bar.class) { System.out.println("synchronized block " + Thread.currentThread().getName()); System.out.println("synchronized block " + Thread.currentThread().getName() + " end"); } } public static void main(String[] args) { Bar b1 = new Bar(); Thread t1 = new Thread(b1); Thread t2 = new Thread(b1); Bar b2 = new Bar(); Thread t3 = new Thread(b2); t1.setName("t1"); t2.setName("t2"); t3.setName("t3"); t1.start(); t2.start(); t3.start(); }} |
Output:
t1
t3
synchronized block t1
synchronized block t1 end
t2
synchronized block t2
synchronized block t2 end
synchronized block t3
synchronized block t3 end
The code reflects the change that this has been replaced with Bar.class level lock. Note that the order of output is generated from the two lines:
System.out.println("synchronized block " + Thread.currentThread().getName());System.out.println("synchronized block " + Thread.currentThread().getName() + " end"); |
is going to be executed for the same thread which entered the synchronized block.
In the ab
Read more: http://www.javaexperience.com/object-and-class-level-locks-in-java/#ixzz3nsk8RjVz
Comments
Post a Comment