Object-level locking in Java controls concurrent access at the instance level, ensuring safe interaction with object data in multithreaded environments. It allows threads to coordinate execution when working on the same object. This mechanism helps maintain consistency without affecting other object instances.
- Applied using synchronized on non-static methods or blocks
- Ensures mutual exclusion only for threads accessing the same object
- 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