Lock and Monitor in Java are both used to manage synchronization and control access to shared resources in multithreading. They help ensure thread safety but differ in flexibility and usage.
- Both are used to achieve synchronization in concurrent programming
- Monitor is implicit (synchronized), while Lock is explicit and more flexible
- Lock provides advanced features compared to basic Monitor functionality
Monitor
A monitor in Java is a mechanism used to control access to shared resources in multithreading. It ensures that only one thread can access a synchronized block or method at a time.
- Every Java object has an intrinsic lock and can act as a monitor.
- Only one thread can hold the monitor lock at a time; others must wait.
- Used with
synchronized,wait(),notify(), andnotifyAll()for thread communication.
import java.io.*;
class SharedDataPrinter
{
// Monitor implementation is carried on by Using synchronous method
synchronized public void display(String str)
{
for (int i = 0; i < str.length(); i++)
{
System.out.print(str.charAt(i));
// Try-catch block for exceptions because sleep() method is used
try
{
// Making thread to sleep for nanoseconds as passed in the arguments Thread.sleep(100);
}
catch (Exception e) {
}
}
}
}
class Thread1 extends Thread {
SharedDataPrinter p;
public Thread1(SharedDataPrinter p)
{
this.p = p;
}
public void run()
{
p.display("Geeks");
}
}
class Thread2 extends Thread {
SharedDataPrinter p;
public Thread2(SharedDataPrinter p) { this.p = p; }
public void run()
{
p.display(" for Geeks");
}
}
class Geeks
{
public static void main(String[] args)
{
SharedDataPrinter printer = new SharedDataPrinter();
Thread1 t1 = new Thread1(printer);
Thread2 t2 = new Thread2(printer);
t1.start();
t2.start();
}
}
Output
Geeks for Geeks
Explanation: Only one thread prints at a time because the synchronized method locks the monitor.
Lock in Java
Lock is a tool for controlling access to shared resources by multiple threads. It’s part of the java.util.concurrent.locks package, introduced in Java 5 and is an alternative to the traditional synchronized keyword.
Below is the illustration which demonstrates the functioning of basic locks.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Geeks {
// Shared resource accessed by multiple threads
private static int sharedResource = 0;
// ReentrantLock for thread synchronization
private static final Lock lock = new ReentrantLock();
public static void main(String[] args) {
// Creating two threads to increment the shared resource
Thread t1 = new Thread(new IncrementTask());
Thread t2 = new Thread(new IncrementTask());
// Start both threads
t1.start();
t2.start();
try {
// Wait for both threads to complete
t1.join();
t2.join();
} catch (InterruptedException e) {
System.out.println("Thread interrupted");
}
// Print final value of shared resource
System.out.println("Final value of sharedResource: "
+ sharedResource);
}
// Task to increment the shared resource
static class IncrementTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
// Acquire the lock
lock.lock();
try {
sharedResource++;
} finally {
// Release the lock
lock.unlock();
}
}
}
}
}
Output
Final value of sharedResource: 2000
Explanation:
- sharedResource is a common variable accessed by two threads.
- ReentrantLock ensures only one thread updates it at a time.
- Both threads increment the value 1000 times each.
- lock.lock() and lock.unlock() provide safe access.
- Final output = 2000, proving thread-safety.
Lock vs Monitor
| Aspect | Monitor (synchronized) | Lock (ReentrantLock) |
|---|---|---|
| Origin | JVM intrinsic, low-level primitive | Java 5, high-level API |
| Implementation | Implicit, JVM-managed | Explicit, programmer-managed |
| Critical Section Management | Automatic | Manual (lock() / unlock()) |
| Thread Queueing | JVM manages waiting threads | Programmer can choose fairness policies |
| Features | Simple mutual exclusion | Advanced: fairness, interruptible, tryLock, multiple conditions |
| Performance | Lightweight for small threads | Slightly higher overhead, but more flexible |
| Usage | Simple synchronization, small thread pools | Complex synchronization, high concurrency scenarios |
| Deadlock Handling | Less control | More explicit control but can still occur |
Note: As monitors themselves are implemented with the necessary support of locks, it is often said that they are not different but complementary in their existence.