JAVA - Zero to Hero / Multithreading

Thread Synchronization

✅ What is it?

  • Thread Synchronization is a way to control access to shared resources (like variables, objects, files) in multithreading.

  • It prevents data inconsistency when multiple threads try to read/write the same resource at the same time.


🔄 Why Synchronization?

Without synchronization:

  • Two threads can modify shared data at the same time.

  • This causes race conditions, where the result depends on thread timing → very dangerous!


🛠️ How to Synchronize in Java?

1️⃣ Using synchronized Keyword

You can synchronize:

🔧 Code:

class Counter {
    int count = 0;

    // Synchronized method
    synchronized void increment() {
        count++;
    }
}

public class SyncExample {
    public static void main(String[] args) throws InterruptedException {
        Counter c = new Counter();

        // Create first thread
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                c.increment();
            }
        });

        // Create second thread
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                c.increment();
            }
        });

        // Start both threads
        t1.start();
        t2.start();

        // Wait for both threads to finish
        t1.join();
        t2.join();

        // Print final count
        System.out.println("Final count: " + c.count);
    }
}

Accordion Item 1

🧠 Explanation:

  1. Class and Variable

  • We created a class Counter that has an integer variable count which starts at 0.

  1. Synchronized Method

synchronized void increment() {
    count++;
}
  • This method increases the value of count by 1.

  • The synchronized keyword ensures that only one thread at a time can enter this method.

  1. Threads

  • Two threads t1 and t2 are created.

  • Each thread runs a loop 1000 times, calling c.increment().

  1. Why Synchronization is Needed

  • Without synchronized, both threads might access and modify count at the same time, causing some increments to be lost.

  • With synchronized, each increment operation is handled one at a time, preventing race conditions.

  1. Final Output

  • Total expected increments: 1000 (from t1) + 1000 (from t2) = 2000.

  • Synchronization ensures we always get 2000 as output.


🧪 Example:

Suppose two threads are updating the same balance.

Without synchronization:

  • One thread might read balance = 1000, another also reads 1000, both try to withdraw, resulting in incorrect balance.

With synchronization:

  • Only one thread can access the withdraw() method at a time.


✅ Points:

  • synchronized makes sure only one thread at a time enters the block/method.

  • It locks the object while one thread is using it.

  • Other threads wait until the lock is released.


🧠 Example Use Cases:

  • Banking systems

  • Inventory management

  • Booking systems (like train or movie seats)

  • Logging to a shared file


⚠️ Important Notes:

  • Synchronization slows down performance slightly, but ensures correctness.

  • Overusing it can cause deadlocks (threads waiting forever for each other).

  • Use it only when necessary on shared resources.


📝 Summary Table

Concept

Meaning

synchronized

Keyword to lock methods/blocks

Shared Resource

Data used by multiple threads

Race Condition

Threads changing data unpredictably

Lock

Prevents multiple threads at once

Deadlock

Threads stuck waiting for each other