Synchronization

Back

Loading concept...

🎭 The Restaurant Kitchen: A Story About Thread Synchronization

Imagine you’re running a busy restaurant kitchen. Multiple chefs (threads) are cooking dishes at the same time. But what happens when two chefs need the same pan at once? Chaos! That’s exactly what thread synchronization solves.


🍳 What is Thread Synchronization?

The Problem: Imagine two chefs both try to pour soup into the same bowl at the exact same time. The soup spills everywhere! In programming, this is called a race condition.

The Solution: Thread synchronization is like having a “One Chef at a Time” rule for shared equipment.

// Without synchronization - CHAOS!
// Chef 1 and Chef 2 both grab the pan
int soupLevel = 0;
// Both chefs add soup at same time
// Result: Unpredictable!

Real Life Example:

  • Two people editing the same document = confusion
  • One person edits while other waits = safe!

🔐 The synchronized Keyword: The Kitchen Pass

Think of synchronized like a kitchen pass - a special token. Only the chef holding the pass can use the shared equipment.

Method-Level Synchronization

public class Kitchen {
    private int plates = 10;

    // Only ONE chef can run this
    public synchronized void usePlate() {
        if (plates > 0) {
            plates--;
            System.out.println("Used plate");
        }
    }
}

Block-Level Synchronization

Sometimes you only need to protect a small part:

public void cookDish() {
    // Multiple chefs can prep
    prepIngredients();

    // But only ONE can use stove
    synchronized(this) {
        useStove();
    }
}

Static Synchronization

For shared resources across ALL kitchens:

public class Kitchen {
    private static int totalOrders = 0;

    // Locks the ENTIRE class
    public static synchronized void addOrder() {
        totalOrders++;
    }
}

🗝️ Locking Strategies: Different Kitchen Rules

graph TD A["Locking Strategies"] --> B["Intrinsic Lock"] A --> C["Object Lock"] A --> D["Class Lock"] B --> E["synchronized method"] C --> F["synchronized on object"] D --> G["synchronized on .class"]

1. Intrinsic Lock (Built-in)

Every object in Java has a hidden lock. Like every pan having its own tag.

// Uses 'this' object's lock
public synchronized void cook() {
    // Only one thread here
}

2. Object Lock

Lock on a specific object:

private final Object panLock = new Object();

public void usePan() {
    synchronized(panLock) {
        // Protected code
    }
}

3. Class Lock

Lock shared by ALL instances:

public static synchronized void globalRule() {
    // All kitchens follow this
}

// Same as:
synchronized(Kitchen.class) { }

📢 wait(), notify(), and notifyAll(): Kitchen Communication

Imagine a chef needs ingredients from the storage. If storage is empty, the chef waits. When ingredients arrive, someone notifies the waiting chef.

wait() - “I’ll Wait Here”

synchronized(storage) {
    while (storage.isEmpty()) {
        storage.wait(); // Chef sleeps
    }
    // Use ingredients
}

notify() - “Wake Up ONE Chef”

synchronized(storage) {
    storage.addIngredients();
    storage.notify(); // Wakes ONE chef
}

notifyAll() - “Everyone Wake Up!”

synchronized(storage) {
    storage.addIngredients();
    storage.notifyAll(); // All chefs wake
}

Important Rules:

  • Must call inside synchronized block
  • wait() releases the lock while waiting
  • notify() wakes ONE random waiting thread
  • notifyAll() wakes ALL waiting threads

🤝 Inter-thread Communication: The Producer-Consumer Kitchen

Classic example: One chef produces dishes, another consumes (serves) them.

class KitchenCounter {
    private Queue<String> dishes = new LinkedList<>();
    private int maxDishes = 5;

    public synchronized void addDish(String dish)
            throws InterruptedException {
        // Wait if counter is full
        while (dishes.size() >= maxDishes) {
            wait();
        }
        dishes.add(dish);
        notifyAll(); // Tell servers
    }

    public synchronized String takeDish()
            throws InterruptedException {
        // Wait if no dishes
        while (dishes.isEmpty()) {
            wait();
        }
        String dish = dishes.poll();
        notifyAll(); // Tell chefs
        return dish;
    }
}
graph TD A["Producer Chef"] -->|makes dish| B["Counter"] B -->|dish ready| C["Consumer Server"] C -->|counter empty| D["wait"] A -->|counter full| E["wait"] D -->|notifyAll| A E -->|notifyAll| C

💀 Deadlock: The Deadly Kitchen Dance

Deadlock happens when two chefs are stuck waiting for each other forever.

The Scenario:

  • Chef A holds the pan, needs the spatula
  • Chef B holds the spatula, needs the pan
  • Both wait forever! 🔄
// DEADLOCK EXAMPLE - DON'T DO THIS!
Object pan = new Object();
Object spatula = new Object();

// Thread 1
synchronized(pan) {
    Thread.sleep(100);
    synchronized(spatula) { // STUCK!
        cook();
    }
}

// Thread 2
synchronized(spatula) {
    Thread.sleep(100);
    synchronized(pan) { // STUCK!
        cook();
    }
}

How to Prevent Deadlock

Rule: Always grab locks in the SAME ORDER

// SAFE - Both threads lock in same order
// Thread 1 AND Thread 2
synchronized(pan) {
    synchronized(spatula) {
        cook();
    }
}
graph TD A["Deadlock Prevention"] --> B["Same Lock Order"] A --> C["Timeout on Locks"] A --> D["Avoid Nested Locks"] A --> E["Use tryLock"]

⚡ The volatile Keyword: The Kitchen Bulletin Board

Imagine a bulletin board in the kitchen. When head chef writes “LUNCH RUSH”, every chef should see it immediately.

volatile ensures:

  1. Changes are visible to all threads instantly
  2. No caching of the value
class Kitchen {
    // Without volatile - chefs might see old value
    // With volatile - always see latest
    private volatile boolean isRushHour = false;

    public void startRush() {
        isRushHour = true; // All threads see this
    }

    public void checkRush() {
        if (isRushHour) {
            workFaster();
        }
    }
}

When to Use volatile

Use volatile Use synchronized
Simple flag Counter++
Status check Multiple operations
One writer Multiple writers

volatile does NOT help with:

volatile int count = 0;
count++; // NOT SAFE! (read-modify-write)

🛡️ Thread-safe Collections: Ready-Made Safe Containers

Instead of adding locks yourself, Java provides pre-built safe containers!

The Problem with Regular Collections

// NOT SAFE for multiple threads
List<String> orders = new ArrayList<>();
// Two chefs adding orders = CHAOS

Thread-Safe Solutions

1. Synchronized Wrappers

List<String> safeList =
    Collections.synchronizedList(
        new ArrayList<>()
    );

2. Concurrent Collections (Better!)

// ConcurrentHashMap - Fast & Safe
Map<String, Integer> orders =
    new ConcurrentHashMap<>();

// CopyOnWriteArrayList - Safe for reads
List<String> menu =
    new CopyOnWriteArrayList<>();

// BlockingQueue - Producer-Consumer
BlockingQueue<String> dishes =
    new LinkedBlockingQueue<>();
graph LR A["Thread-Safe Collections"] --> B["Synchronized Wrappers"] A --> C["Concurrent Collections"] B --> D["synchronizedList"] B --> E["synchronizedMap"] C --> F["ConcurrentHashMap"] C --> G["CopyOnWriteArrayList"] C --> H["BlockingQueue"]

Quick Comparison

Collection Best For
ConcurrentHashMap Fast key-value access
CopyOnWriteArrayList Read-heavy, rare writes
BlockingQueue Producer-Consumer
ConcurrentLinkedQueue High-throughput queue

🎯 Quick Reference Summary

Concept Kitchen Analogy Java Tool
Synchronization Kitchen pass synchronized
Lock Equipment tag Object lock
wait/notify “Ingredients ready!” wait(), notify()
Deadlock Chefs stuck waiting Prevent with order
volatile Bulletin board volatile keyword
Thread-safe collections Pre-labeled containers ConcurrentHashMap

🚀 Key Takeaways

  1. synchronized = Only one thread at a time
  2. wait/notify = Threads talk to each other
  3. Deadlock = Avoid by consistent lock ordering
  4. volatile = Instant visibility, not atomicity
  5. Thread-safe collections = Use them instead of manual locks!

Now you’re ready to run a synchronized kitchen where every chef works in harmony! 🎉

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.