Differences Between synchronized and Lock in Java with Code Examples
This article explains Java's thread synchronization mechanisms by comparing synchronized blocks with the Lock interface, detailing thread basics, lifecycle methods, lock types, code demonstrations, fairness settings, and underlying JVM implementations, helping readers understand when and how to use each construct effectively.
Yesterday, while reviewing interview experiences shared by others, I encountered the use of Lock and recalled the differences between synchronized and Lock that appeared in a recent interview. I decided to organize the distinctions, summarize common issues with synchronized, and provide simple demos of Lock usage.
Technical Points
1. Threads and Processes
A program requires at least one process, and each process contains at least one thread. Threads are the smallest execution units, while processes are the units of resource allocation and scheduling. All subsequent discussions are based on threads.
2. Important Thread Methods
start(): begins execution of the thread.
stop(): forcibly terminates the thread.
join(): waits for the thread to finish.
sleep(): puts the thread into a waiting state.
run(): the method that contains the thread's work; invoked directly or via start().
Note that wait() and notify() belong to Object, not Thread. wait() releases the object lock, while sleep() does not.
3. Thread States
New: Thread object created but start() not called.
Runnable: After start(), the thread is ready to run.
Running: The thread holds the CPU and executes run().
Blocked: The thread is paused (e.g., by sleep()).
Terminated: Execution has completed.
4. Lock Types
Reentrant lock: a thread can reacquire the lock it already holds.
Interruptible lock: can be interrupted while waiting for the lock.
Fair lock: grants the lock to the longest‑waiting thread.
Read‑write lock: allows multiple concurrent reads but exclusive writes.
synchronized vs. Lock
The differences are summarized in a comparison table (image below).
Below are several simple demos that illustrate typical Lock usage.
Lock Interface Overview
public interface Lock {
/** Acquires the lock. */
void lock();
/** Acquires the lock unless the current thread is interrupted. */
void lockInterruptibly() throws InterruptedException;
/** Acquires the lock only if it is free at the time of invocation. */
boolean tryLock();
/** Acquires the lock if it is free within the given waiting time. */
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
/** Releases the lock. */
void unlock();
}Key methods: lock(): blocks until the lock is obtained. unlock(): releases the lock. tryLock(): returns false if the lock is already held. tryLock(long, TimeUnit): waits up to the specified time. lockInterruptibly(): allows interruption while waiting.
Typical Usage Examples
Using lock()
package com.brickworkers;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private Lock lock = new ReentrantLock();
private void method(Thread thread) {
lock.lock();
try {
System.out.println("线程名" + thread.getName() + "获得了锁");
} finally {
System.out.println("线程名" + thread.getName() + "释放了锁");
lock.unlock();
}
}
public static void main(String[] args) {
LockTest lockTest = new LockTest();
Thread t1 = new Thread(() -> lockTest.method(Thread.currentThread()), "t1");
Thread t2 = new Thread(() -> lockTest.method(Thread.currentThread()), "t2");
t1.start();
t2.start();
}
}Using tryLock()
package com.brickworkers;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockTest {
private Lock lock = new ReentrantLock();
private void method(Thread thread) {
if (lock.tryLock()) {
try {
System.out.println("线程名" + thread.getName() + "获得了锁");
} finally {
System.out.println("线程名" + thread.getName() + "释放了锁");
lock.unlock();
}
} else {
System.out.println("我是" + Thread.currentThread().getName() + "有人占着锁,我就不要啦");
}
}
public static void main(String[] args) {
LockTest lockTest = new LockTest();
Thread t1 = new Thread(() -> lockTest.method(Thread.currentThread()), "t1");
Thread t2 = new Thread(() -> lockTest.method(Thread.currentThread()), "t2");
t1.start();
t2.start();
}
}These demos show how Lock can be used to acquire and release locks explicitly, and how tryLock allows a thread to back off when the lock is already held.
Fair vs. Non‑Fair Locks
The source of ReentrantLock contains two inner classes: NonfairSync and FairSync. The default constructor creates a non‑fair lock, while passing true creates a fair lock.
public ReentrantLock() {
sync = new NonfairSync(); // default non‑fair lock
}Underlying Implementation of synchronized
At the bytecode level, a synchronized block is compiled into monitorenter and monitorexit instructions. The JVM acquires the monitor on monitorenter (incrementing a lock count for re‑entrancy) and releases it on monitorexit. If an exception occurs, the second monitorexit ensures the lock is released.
Lock Implementation Details
Lockrelies on CAS (compare‑and‑swap) operations and volatile fields to implement optimistic locking. The JDK also provides several optimizations for synchronized such as:
Spin‑waiting and adaptive spinning to avoid costly thread parking.
Lock elimination: the JIT removes unnecessary synchronization when it can prove no data race.
Lock coarsening: merges adjacent synchronized blocks into a larger one.
Lightweight locks and biased locks that reduce overhead for uncontended cases.
Understanding these mechanisms helps developers choose the appropriate synchronization primitive for a given scenario.
Conclusion
The article summarizes the differences between synchronized and Lock, provides practical code examples, and explains the JVM’s internal handling of both mechanisms. While Lock offers more flexibility (fairness, interruptibility, timed acquisition), the author recommends preferring synchronized for most cases due to its simplicity and JVM optimizations.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
