SrcForge

Lesson 51

Synchronization

Synchronization in Java controls access to shared resources among multiple threads, ensuring thread safety and data consistency.

Java Track

Save progress as you learn.

61 lessons

Lesson content

Synchronization in Java is a mechanism used to control access to shared resources by multiple threads. It ensures that only one thread can access a critical section of code at a time, preventing data inconsistency and thread interference.

Definition List

  • Synchronization: A technique that controls access to shared resources among multiple threads.
  • Thread Safety: The ability of a program to function correctly when multiple threads execute concurrently.
  • Shared Resource: A resource such as an object, variable, or method that can be accessed by multiple threads.
  • Critical Section: A block of code that accesses shared resources and must be executed by only one thread at a time.
  • Monitor Lock: An internal lock used by Java to implement synchronization.

How Synchronization Works Internally

Thread Requests Access

Monitor Lock Available?

        Yes

Execute Critical Section

Release Lock

Next Waiting Thread Executes

Example 01: Synchronization Using a Synchronized Block

package com.java.Multi_threading;

// A Sender class
class Sender {
    public void SenderMsg(String msg) {
        System.out.println("\nSending a Message: " + msg);
        try {
            Thread.sleep(800);
        } catch (Exception e) {
            System.out.println("Thread interrupted.");
        }
        System.out.println("\n" + msg + "Sent");
    }
}

// A Sender class for sending a message using Threads
class SenderWThreads extends Thread {
    private String msg;
    Sender sd;

    SenderWThreads(String m, Sender obj) {
        msg = m;
        sd = obj;
    }

    public void run() {
        // Checks that only one thread sends a message at a time.
        synchronized(sd) {
            // synchronizing the sender object
            sd.SenderMsg(msg);
        }
    }
}

// Driver Code
public class ShynchronizedMultithreading {
    public static void main(String args[]) {
        Sender sender = new Sender();
        SenderWThreads sender1 = new SenderWThreads("Hola ", sender);
        SenderWThreads sender2 = new SenderWThreads("Welcome to Programming  ", sender);

        sender1.start();
        sender2.start();

        try {
            sender1.join();
            sender2.join();
        } catch (Exception e) {
            System.out.println("Interrupted");
        }
    }
}

Example 02: Synchronized Method

package com.java.Multi_threading;

class Tables {
    synchronized void printTable(int n) { // synchronized method
        for (int i = 1; i <= 5; i++) {
            System.out.println(n * i);
            try {
                Thread.sleep(400);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

class MyThreads_1 extends Thread {
    Tables t;
    MyThreads_1(Tables t) { this.t = t; }
    public void run() { t.printTable(5); }
}

class MyThreads_2 extends Thread {
    Tables t;
    MyThreads_2(Tables t) { this.t = t; }
    public void run() { t.printTable(100); }
}

public class TestSynchronization2 {
    public static void main(String args[]) {
        Tables obj = new Tables(); // only one object
        MyThreads_1 t1 = new MyThreads_1(obj);
        MyThreads_2 t2 = new MyThreads_2(obj);
        t1.start();
        t2.start();
    }
}

Types of Synchronization in Java

// Synchronized Method — locks the entire method
synchronized void printTable(int n) { ... }

// Synchronized Block — locks only a specific block
synchronized(objectReference) {
    // critical section
}

Best Practices

  • Synchronize only critical sections — avoid synchronizing unnecessary code.
  • Prefer synchronized blocks over methods for better performance.
  • Keep lock duration short — release locks as quickly as possible.
  • Avoid nested locks to reduce the risk of deadlocks.
  • Use modern concurrency utilities (ReentrantLock, ConcurrentHashMap, ExecutorService) for complex applications.

FAQ

1. What is synchronization in Java?

Synchronization is a mechanism that allows only one thread at a time to access a shared resource, ensuring thread safety and data consistency.

2. What is the difference between a synchronized method and a synchronized block?

A synchronized method locks the entire method, while a synchronized block locks only a specific section of code, making it more efficient.

3. Why is synchronization important in multithreading?

Synchronization prevents race conditions, protects shared data, and ensures that multiple threads execute safely without causing inconsistent results.

Synchronization ensures only one thread accesses a critical section at a time.
Java uses an internal monitor lock (intrinsic lock) to implement synchronization.
synchronized methods lock the entire method; synchronized blocks lock only a specific section.
Without synchronization, multiple threads can cause race conditions and data corruption.
Prefer synchronized blocks over methods — they offer better performance and flexibility.
Avoid nested locks to prevent deadlocks.
Use ReentrantLock or ConcurrentHashMap for advanced concurrency control.

Where Java is used

Java in real-world development

synchronized method

Locks the entire method so only one thread can execute it on the same object at a time.

synchronized block

Locks only a specific block of code, reducing lock duration and improving performance.

Monitor Lock

Java's internal intrinsic lock. Only one thread can hold it at a time; others wait until it is released.

Race Condition

Occurs when multiple threads access shared data simultaneously, causing inconsistent or corrupted results.

Thread Safety

The property of a program that functions correctly when multiple threads execute concurrently.

Deadlock

A situation where two or more threads wait indefinitely for locks held by each other. Avoid nested locks to prevent it.

Prev: Runtime ClassBack to hub