Java thread life cycle and wait/notify

 




Java thread life cycle and wait/notify

01.Java Thread Life Cycle — The 6 Main States

New → Runnable → Running → Blocked / Waiting / Timed Waiting → Terminated


1. New: Thread is created, but start() hasn’t been called yet.

Thread t = new Thread(() -> {});


2. Runnable: Thread is ready to run, but waiting for CPU time.

t.start(); // thread goes to Runnable state


3. Running: CPU picks the thread and runs its run() method.


4. Blocked:  Thread is trying to enter a synchronized block, but another thread holds the lock.

synchronized(obj) {

    // if another thread is inside this block, you are BLOCKED

}


5. Waiting / Timed Waiting: The thread is waiting for another thread to signal/notify it.

There are two kinds:

  Waiting: infinite until notify()

  Timed Waiting: waits for a timeout (e.g., sleep(1000))



wait() and notify() — How They Work


These are used for inter-thread communication — not locking.


wait(): Tells the thread ->  “Go to sleep and release the lock. Wait for someone to notify you.”

notify(): Wakes up one thread that's waiting on the same object.

notifyAll(): Wakes up all threads waiting on the object.


Object lock = new Object();


Thread threadA = new Thread(() -> {

    synchronized (lock) {

        try {

            System.out.println("Thread A: waiting...");

            lock.wait(); // releases lock and waits

            System.out.println("Thread A: resumed!");

        } catch (InterruptedException e) {}

    }

});


Thread threadB = new Thread(() -> {

    synchronized (lock) {

        System.out.println("Thread B: notifying...");

        lock.notify(); // wakes Thread A

    }

});


threadA.start();

Thread.sleep(1000); // give A time to wait

threadB.start();


Output:

Thread A: waiting...

Thread B: notifying...

Thread A: resumed!


IMPORANT:

In a normal synchronized block, when Thread 1 releases the lock, Thread 2 automatically gets the lock when it's available — there is no need for notify()


How it works step-by-step:


1. Thread 1 enters:

   synchronized (lock) {

       // doing something

   }



2. Thread 2 also wants to enter the same synchronized(lock):

    It is BLOCKED (not WAITING)

    It keeps checking (handled by JVM) — not busy-looping, but the JVM manages this.


3. Thread 1 finishes, exits the synchronized block — the lock is released.


4. Thread 2 is notified by JVM internals, and it enters automatically when it gets CPU time.

No wait() or notify() is needed here.


But when do we need wait() and notify()?

Only when you want to pause a thread manually and make it wait for a specific condition, like:

  •   Shared queue is empty
  •   A flag is not ready
  •   Waiting for some other task to complete


Comments

Popular posts from this blog

Database - Topics

02. Spring – Creating spring project clone it with GIT step by step.