---
title: "Synchronization and Inter-thread Communication in Java"  
description: "Synchronization and Inter-thread Communication in Java"  
author: "ICSM Computer"  
published: 2025-04-24  
updated: 2025-04-24  
canonical: https://www.mindstick.com/interview/34067/synchronization-and-inter-thread-communication-in-java  
category: "java"  
tags: ["java"]  
reading_time: 7 minutes  

---

# Synchronization and Inter-thread Communication in Java

In a multi-threaded environment, **synchronization** ensures that multiple threads can safely access shared resources without causing inconsistent data or conflicts. **Inter-thread communication** allows threads to communicate with each other, often used for coordinating the execution of threads.

## 1. Synchronization in Java

Synchronization in Java is done using the `synchronized` keyword, which can be applied to methods or blocks of code.

### a. Synchronized Method

When a method is declared as `synchronized`, only one thread at a time can execute it, ensuring mutual exclusion.

## Example:

```java
class Counter {
    private int count = 0;

    // Synchronized method to ensure thread safety
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class SynchronizationExample {
    public static void main(String[] args) {
        Counter counter = new Counter();

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

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Output the final count
        System.out.println("Count: " + counter.getCount());
    }
}
```

### b. Synchronized Block

A **synchronized block** is used to lock only a particular section of code, instead of the whole method. It helps to minimize the scope of synchronization, improving performance.

## Example:

```java
class Counter {
    private int count = 0;

    public void increment() {
        synchronized (this) {  // Lock only this block
            count++;
        }
    }

    public int getCount() {
        return count;
    }
}
```

## 2. Inter-thread Communication

Java provides mechanisms for threads to communicate and coordinate with each other using the `wait()`, `notify()`, and `notifyAll()` methods. These methods are available in the `Object` class and can be used for synchronization.

### a. `wait()`, `notify()`, and `notifyAll()` Methods

- `wait()`: Makes the current thread wait until another thread calls `notify()` or `notifyAll()` on the same object.
- `notify()`: Wakes up a single thread that is waiting on the object's monitor.
- `notifyAll()`: Wakes up all threads waiting on the object's monitor.

## Example: Producer-Consumer Problem

Here’s a simple example where one thread produces data and another consumes it.

```java
class SharedResource {
    private int data;
    private boolean available = false;

    public synchronized void produce(int value) throws InterruptedException {
        while (available) {
            wait(); // Wait if data is already available
        }
        data = value;
        available = true;
        notify(); // Notify consumer that data is ready
    }

    public synchronized int consume() throws InterruptedException {
        while (!available) {
            wait(); // Wait if no data is available
        }
        available = false;
        notify(); // Notify producer to produce data
        return data;
    }
}

public class ProducerConsumerExample {
    public static void main(String[] args) {
        SharedResource sharedResource = new SharedResource();

        // Producer thread
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    sharedResource.produce(i);
                    System.out.println("Produced: " + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // Consumer thread
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    int value = sharedResource.consume();
                    System.out.println("Consumed: " + value);
                    Thread.sleep(1500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}
```

### b. Important Points for Inter-thread Communication

- **Synchronization** ensures that only one thread can access a shared resource at a time.
- `wait()` **and** `notify()` must be called from within a **synchronized block** (or method), as these methods operate on the monitor of the object.

### 3. Deadlock and Thread Safety

Deadlock occurs when two or more threads are blocked forever, waiting for each other to release a resource. To avoid deadlock, you can:

- Use timeouts in `wait()`.
- Ensure a consistent locking order.

## Answers

### Answer by ICSM Computer

In a multi-threaded environment, **synchronization** ensures that multiple threads can safely access shared resources without causing inconsistent data or conflicts. **Inter-thread communication** allows threads to communicate with each other, often used for coordinating the execution of threads.

## 1. Synchronization in Java

Synchronization in Java is done using the `synchronized` keyword, which can be applied to methods or blocks of code.

### a. Synchronized Method

When a method is declared as `synchronized`, only one thread at a time can execute it, ensuring mutual exclusion.

## Example:

```java
class Counter {
    private int count = 0;

    // Synchronized method to ensure thread safety
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class SynchronizationExample {
    public static void main(String[] args) {
        Counter counter = new Counter();

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

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Output the final count
        System.out.println("Count: " + counter.getCount());
    }
}
```

### b. Synchronized Block

A **synchronized block** is used to lock only a particular section of code, instead of the whole method. It helps to minimize the scope of synchronization, improving performance.

## Example:

```java
class Counter {
    private int count = 0;

    public void increment() {
        synchronized (this) {  // Lock only this block
            count++;
        }
    }

    public int getCount() {
        return count;
    }
}
```

## 2. Inter-thread Communication

Java provides mechanisms for threads to communicate and coordinate with each other using the `wait()`, `notify()`, and `notifyAll()` methods. These methods are available in the `Object` class and can be used for synchronization.

### a. `wait()`, `notify()`, and `notifyAll()` Methods

- `wait()`: Makes the current thread wait until another thread calls `notify()` or `notifyAll()` on the same object.
- `notify()`: Wakes up a single thread that is waiting on the object's monitor.
- `notifyAll()`: Wakes up all threads waiting on the object's monitor.

## Example: Producer-Consumer Problem

Here’s a simple example where one thread produces data and another consumes it.

```java
class SharedResource {
    private int data;
    private boolean available = false;

    public synchronized void produce(int value) throws InterruptedException {
        while (available) {
            wait(); // Wait if data is already available
        }
        data = value;
        available = true;
        notify(); // Notify consumer that data is ready
    }

    public synchronized int consume() throws InterruptedException {
        while (!available) {
            wait(); // Wait if no data is available
        }
        available = false;
        notify(); // Notify producer to produce data
        return data;
    }
}

public class ProducerConsumerExample {
    public static void main(String[] args) {
        SharedResource sharedResource = new SharedResource();

        // Producer thread
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    sharedResource.produce(i);
                    System.out.println("Produced: " + i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // Consumer thread
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    int value = sharedResource.consume();
                    System.out.println("Consumed: " + value);
                    Thread.sleep(1500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}
```

### b. Important Points for Inter-thread Communication

- **Synchronization** ensures that only one thread can access a shared resource at a time.
- `wait()` **and** `notify()` must be called from within a **synchronized block** (or method), as these methods operate on the monitor of the object.

### 3. Deadlock and Thread Safety

Deadlock occurs when two or more threads are blocked forever, waiting for each other to release a resource. To avoid deadlock, you can:

- Use timeouts in `wait()`.
- Ensure a consistent locking order.


---

Original Source: https://www.mindstick.com/interview/34067/synchronization-and-inter-thread-communication-in-java

Copyright © MindStick Software Pvt. Ltd. This Markdown version is provided for developers, AI systems, and offline reading.
