Optimistic vs Pessimistic Locks in Java: Concepts, Code & Comparison
This article explains the principles of optimistic and pessimistic locking in Java, shows how atomic classes and synchronized constructs implement them, provides runnable code examples, and compares their strategies, scenarios, performance, and typical implementations.
Optimistic Lock
Optimistic lock assumes that conflicts are rare during concurrent access, so it does not lock when reading data and only checks for modifications when updating. If another thread changed the data, the update is aborted or retried. It is typically implemented using a version number or CAS mechanism.
In Java, atomic variable classes such as AtomicInteger and LongAdder use CAS to realize optimistic locking.
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while (!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
// CAS underlying implementation
return var5;
}Pessimistic Lock
Pessimistic lock assumes that conflicts are likely, so it locks the data when accessing it and releases the lock after the update. It is usually implemented with mutexes or read‑write locks.
In Java, Synchronized and ReentrantLock are typical pessimistic lock implementations. Because only one thread can hold the lock at a time, other threads block, leading to context switches and possible deadlocks.
public class PessimisticLockTest {
private int counter = 0;
// method locked to ensure only one thread modifies counter
public synchronized void increment() {
counter++;
}
public synchronized int getCounter() {
return counter;
}
public static void main(String[] args) throws InterruptedException {
PessimisticLockTest plt = new PessimisticLockTest();
// create two threads to execute increment concurrently
Thread t1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
plt.increment();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
plt.increment();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Counter: " + plt.getCounter());
}
}
// Counter: 2000Comparison of Pessimistic and Optimistic Locks
Lock strategy: Pessimistic – lock before operating on the resource; Optimistic – no lock, assume no conflict, retry on conflict.
Applicable scenarios: Pessimistic – high concurrency with strict data consistency; Optimistic – high concurrency with low conflict probability.
Performance: Pessimistic – good under low concurrency, may cause thread blocking under high concurrency; Optimistic – better performance, especially when conflicts are rare.
Implementation: Pessimistic – Synchronized, ReentrantLock etc.; Optimistic – CAS, Atomic classes etc.
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.
Xuanwu Backend Tech Stack
Primarily covers fundamental Java concepts, mainstream frameworks, deep dives into underlying principles, and JVM internals.
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.
