Mawia
Mawia

Reputation: 4310

Thread waiting another thread

I need an explanation here.

 public static void main(String[] args) {
    FirstThread obj = new FirstThread();
    for (int i = 1; i <= 10; i++) {
      new WaiterThread(obj).start();
    }
    obj.start();
  }

public class FirstThread extends Thread {
  @Override
  public void run() {
    // Do something
  }
}


public class WaiterThread extends Thread {
  Object obj;

  WaiterThread(Object obj) {
    this.obj = obj;
  }

  @Override
  public void run() {
    synchronized (obj) {
           obj.wait();
    }
  }
}

10 threads are created for WaiterThread and are waiting for a single FirstThread object. After FirstThread terminates, all WaiterThread s resumed without obj.notify() or obj.notifyAll() being called anywhere.

Does that mean WaiterThread s stopped waiting for FirstThread because it gets terminated?

Upvotes: 4

Views: 146

Answers (3)

Marko Topolnik
Marko Topolnik

Reputation: 200296

As per the documentation of the Thread class, a dying thread calls notifyAll on the instance which represents it.

Furthermore, quoting the same documentation:

It is recommended that applications not use wait, notify, or notifyAll on Thread instances.

Of course, the same recommendation applies to instances of Thread subclasses, which is what your code is doing.

Upvotes: 6

Aniket Thakur
Aniket Thakur

Reputation: 69025

I modified a code a bit as below

main() method remains the same

 public static void main(String[] args) {
    FirstThread obj = new FirstThread();
    for (int i = 1; i <= 10; i++) {
      new WaiterThread(obj).start();
    }
    obj.start();
  }

change is as follows

class WaiterThread extends Thread {
    Object obj;

    WaiterThread(Object obj) {
        this.obj = obj;
    }

    @Override
    public void run() {
        synchronized (obj) {
            try {
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread " + this.getId() + "started");
        }
        System.out.println("Out of sync block by " + this.getId());
    }
}

ant the output I got is

FirstThread Started
Thread 19started
Out of sync block by 19
Thread 18started
Out of sync block by 18
Thread 17started
Out of sync block by 17
Thread 16started
Out of sync block by 16
Thread 15started
Out of sync block by 15
Thread 14started
Out of sync block by 14
Thread 13started
Out of sync block by 13
Thread 12started
Out of sync block by 12
Thread 11started
Out of sync block by 11
Thread 10started
Out of sync block by 10

So you have your answer. They are not started simultaneously! FirstThread calls notifyAll() while dying out which notifies all but each thread can have the lock only one at a time. So though every thread is notified only one thread executes at a time.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 692151

This is a side-effect of the fact that when a thread terminates, it invokes this.notifyAll() (as documented in the javadoc of Thread.join()). The same javadoc also makes the following recommendation:

It is recommended that applications not use wait, notify, or notifyAll on Thread instances

Upvotes: 6

Related Questions