Lesson Completion
Back to course

Locks and Atomic Variables: Advanced Synchronization

Advanced
25 minutes4.7Java

1. The Hook (The "Byte-Sized" Intro)

In a Nutshell: ReentrantLock offers more flexibility than synchronized: tryLock() (non-blocking), timed locks, interruptible locks, fairness policies. ReadWriteLock allows multiple readers OR single writer (better for read-heavy scenarios). Condition variables replace wait/notify. Atomic variables (AtomicInteger, AtomicReference) provide lock-free thread-safety via CAS (Compare-And-Swap) operations—faster than synchronized for simple operations!

Think of hotel rooms. synchronized = one master key. ReentrantLock = smart lock with PIN codes, timeouts, guest list. ReadWriteLock = library (many readers, one writer). Atomic = self-service kiosk (no queue needed)!


2. Conceptual Clarity (The "Simple" Tier)

💡 The Analogy

  • synchronized: Automatic door lock (simple, inflexible)
  • ReentrantLock: Smart lock (timeout, try without blocking)
  • Atomic: Vending machine (no lock needed, CAS = coin slot accepts only if price matches)

3. Technical Mastery (The "Deep Dive")

ReentrantLock vs synchronized

java
// synchronized (implicit lock) public synchronized void method() { // Locked automatically } // ReentrantLock (explicit lock) private final Lock lock = new ReentrantLock(); public void method() { lock.lock(); try { // Critical section } finally { lock.unlock(); // MUST unlock in finally! } }

Atomic Variables

java
// ❌ synchronized (heavyweight) private int count = 0; public synchronized void increment() { count++; } // ✅ Atomic (lock-free) private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); // CAS operation }

4. Interactive & Applied Code

java
import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; public class AdvancedSynchronizationDemo { public static void main(String[] args) { demonstrateReentrantLock(); demonstrateReadWriteLock(); demonstrateAtomicVariables(); } static void demonstrateReentrantLock() { System.out.println("=== REENTRANT LOCK ==="); ReentrantLock lock = new ReentrantLock(); // Try-lock with timeout try { if (lock.tryLock(100, java.util.concurrent.TimeUnit.MILLISECONDS)) { try { System.out.println("Lock acquired"); // Critical section } finally { lock.unlock(); } } else { System.out.println("Could not acquire lock"); } } catch (InterruptedException e) { e.printStackTrace(); } // Fair lock (FIFO order) ReentrantLock fairLock = new ReentrantLock(true); // fair=true } static void demonstrateReadWriteLock() { System.out.println("\n=== READ-WRITE LOCK ==="); ReadWriteLock rwLock = new ReentrantReadWriteLock(); // Multiple readers can hold lock simultaneously Runnable reader = () -> { rwLock.readLock().lock(); try { System.out.println(Thread.currentThread().getName() + " reading"); Thread.sleep(1000); } catch (Exception e) { } finally { rwLock.readLock().unlock(); } }; // Only one writer at a time Runnable writer = () -> { rwLock.writeLock().lock(); try { System.out.println(Thread.currentThread().getName() + " writing"); Thread.sleep(1000); } catch (Exception e) { } finally { rwLock.writeLock().unlock(); } }; new Thread(reader, "Reader-1").start(); new Thread(reader, "Reader-2").start(); new Thread(writer, "Writer").start(); } static void demonstrateAtomicVariables() { System.out.println("\n=== ATOMIC VARIABLES ==="); AtomicInteger counter = new AtomicInteger(0); // incrementAndGet() - atomic operation System.out.println("Increment: " + counter.incrementAndGet()); // 1 // compareAndSet() - CAS operation boolean updated = counter.compareAndSet(1, 10); System.out.println("CAS updated: " + updated); // true System.out.println("Value: " + counter.get()); // 10 // AtomicReference for objects AtomicReference<String> ref = new AtomicReference<>("Initial"); ref.compareAndSet("Initial", "Updated"); System.out.println("Reference: " + ref.get()); } } // Condition example class BoundedBuffer { private final Lock lock = new ReentrantLock(); private final Condition notFull = lock.newCondition(); private final Condition notEmpty = lock.newCondition(); private final Object[] items = new Object[10]; private int count, putIndex, takeIndex; public void put(Object item) throws InterruptedException { lock.lock(); try { while (count == items.length) { notFull.await(); // Better than wait() } items[putIndex] = item; putIndex = (putIndex + 1) % items.length; count++; notEmpty.signal(); // Better than notify() } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) { notEmpty.await(); } Object item = items[takeIndex]; takeIndex = (takeIndex + 1) % items.length; count--; notFull.signal(); return item; } finally { lock.unlock(); } } }

5. The Comparison & Decision Layer

FeaturesynchronizedReentrantLockAtomic
Lock acquisitionAutomaticManual (lock/unlock)Lock-free
Try-lock❌ No✅ YesN/A
Timeout❌ No✅ YesN/A
Fairness❌ No✅ OptionalN/A
PerformanceMediumMediumFast
Use caseSimple lockingAdvanced needsSimple counters

6. The "Interview Corner" (The Edge)

The "Killer" Interview Question: "What is CAS (Compare-And-Swap) and why is it lock-free?" Answer: CAS is hardware-level atomic instruction: "Only update if current value equals expected."

java
// CAS pseudocode boolean compareAndSet(int expect, int update) { // ATOMIC at hardware level (single CPU instruction) if (currentValue == expect) { currentValue = update; return true; } return false; } // Lock-free increment public void increment() { int current; do { current = count.get(); } while (!count.compareAndSet(current, current + 1)); // Retries if another thread changed value }

Lock-free = no thread ever blocks waiting for lock → better scalability!

Pro-Tip: Always unlock in finally block:

java
// ❌ DANGEROUS: Exception before unlock = lock never released! lock.lock(); riskyOperation(); // Might throw exception lock.unlock(); // Never reached! // ✅ SAFE: unlock guaranteed lock.lock(); try { riskyOperation(); } finally { lock.unlock(); // Always releases }

Topics Covered

Java FundamentalsConcurrency

Tags

#java#multithreading#threads#concurrency#parallelism

Last Updated

2025-02-01