Fundamentals 8 min read

Why Use a while Loop Instead of if with wait() in Java Synchronization?

This article explains why a while loop is required rather than an if statement when using wait() inside synchronized blocks, demonstrates the race condition with a bounded buffer example, shows the correct fix, discusses notifyAll versus notify, and illustrates how improper use can lead to deadlocks in Java multithreading.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why Use a while Loop Instead of if with wait() in Java Synchronization?

Why is it while instead of if?

Most people know the common synchronized pattern:

synchronized (obj) {
    while (check pass) {
        wait();
    }
    // do your business
}

The question is why use while instead of if inside the synchronized block.

Example of a bounded queue

static class Buf {
    private final int MAX = 5;
    private final ArrayList<Integer> list = new ArrayList<>();
    synchronized void put(int v) throws InterruptedException {
        if (list.size() == MAX) {
            wait();
        }
        list.add(v);
        notifyAll();
    }
    synchronized int get() throws InterruptedException {
        // line 0
        if (list.size() == 0) { // line 1
            wait(); // line 2
        }
        int v = list.remove(0); // line 4
        notifyAll(); // line 5
        return v;
    }
    synchronized int size() {
        return list.size();
    }
}

Running this code with one producer thread and ten consumer threads quickly throws an IndexOutOfBoundsException because the if check does not re‑evaluate after being notified.

What goes wrong?

A thread A acquires the lock, sees size == 0, calls wait() and releases the lock.

Thread B acquires the lock, also sees size == 0, calls wait() and releases the lock.

A producer thread adds an element and calls notifyAll(), waking both A and B.

A reacquires the lock, removes the element successfully.

B then proceeds, still assuming the list is non‑empty, and attempts to remove an element, causing the exception.

The fix is simply to replace the if with a while loop in the get method:

synchronized int get() throws InterruptedException {
    while (list.size() == 0) {
        wait();
    }
    int v = list.remove(0);
    notifyAll();
    return v;
}

When to use notifyAll or notify?

Typical advice says use notifyAll() to wake all waiting threads and notify() to wake a single thread, but the JVM does not guarantee which thread is chosen when notify() is used.

synchronized void put(int v) throws InterruptedException {
    if (list.size() == MAX) {
        wait();
    }
    list.add(v);
    notify();
}

synchronized int get() throws InterruptedException {
    while (list.size() == 0) {
        wait();
    }
    int v = list.remove(0);
    notify();
    return v;
}

JVM insights

When a thread is awakened, the exact thread that will run next is unpredictable.

The synchronized semantics ensure that only one thread can execute the synchronized block at a time.

Potential deadlock scenario

Consider multiple producer (P) and consumer (C) threads interacting with the bounded buffer. If producers use notify() and consumers use while loops, a situation can arise where all remaining threads are waiting for a lock that never becomes available, leading to deadlock.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaconcurrencymultithreadingwait/notify
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.