Object-level lock in Java is used to synchronize non-static methods or blocks so that only one thread can access a particular object at a time. Each object has its own lock, ensuring thread safety for instance-level data.
- Every object has a unique lock (monitor)
- Used with non-static synchronized methods/blocks
- Only one thread per object can execute synchronized code at a time
- Other threads must wait until the lock is released
Methods of Object Level Lock
There are different ways we can lock the object in the thread as below:
Method 1:
public class GeekClass{
public synchronized void GeekMethod(){}
}
Method 2:
public class GeekClass {
public void GeekMethod(){
synchronized (this) {
// other thread safe code }
}
}
Method 3:
public class DemoClass {
private final Object lock = new Object();
public void demoMethod(){
synchronized (lock) {
// other thread safe code }
}
}
Example : Java program to illustrate Object lock concept
// Class
// Extending Runnable interface
class Geek implements Runnable {
// Method of this class
public void run() { Lock(); }
// Synchronization of non-static methods
// (object lock) as different synchronized
// non-static methods are called in both threads
// Then both threads need to acquire the object lock
// After one is acquired, the other thread must wait
// for one thread to finish the executing
// before the other thread starts to execute.
public void Lock()
{
System.out.println(
Thread.currentThread().getName());
synchronized (this)
{
System.out.println(
"in block "
+ Thread.currentThread().getName());
System.out.println(
"in block "
+ Thread.currentThread().getName()
+ " end");
}
}
// Main driver method
public static void main(String[] args)
{
// Creating an object of above class
// in the main() method
Geek g = new Geek();
// Sharing the same object across two Threads
// Here, t1 takes g
Thread t1 = new Thread(g);
// Here, t2 takes g
Thread t2 = new Thread(g);
// Creating another object of above class
Geek g1 = new Geek();
// Here, t3 takes g1
Thread t3 = new Thread(g1);
// setname() method is used to change
// name of the thread
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
// start() method beginning the execution of threads
// as JVM calls the run() method of thread
t1.start();
t2.start();
t3.start();
}
}
Output
t1 t2 t3 in block t1 in block t3 in block t3 end in block t1 end in block t2 in block t2 end
Explanation:
- Threads t1 and t2 share the same object (g), so they compete for the same object lock and execute the synchronized block one at a time
- Thread t3 uses a different object (g1), so it gets a separate lock and can execute independently
- This shows that object-level lock works per object, not per class