sawai singh
sawai singh

Reputation: 57

In Inter thread processes why main thread behave badly, when child executed first?

I am learning threading in java and wrote following code. Here: I am creating two threads (main and t) and i want to implements inter-thread communication. Here is two scenarios :

1) If Main thread executed first/continue then Main thread acquire lock on object "t", release lock and go for waiting state (

synchronized (t) {
    System.out.println("waiting " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
    t.wait();
}

). Child thread take place and complete its work and notify Main thread. Main thread get started and print final output System.out.println(t.total). Its OK, for me.

2) If child thread executed first then child thread complete its working (

synchronized (this) {
    for (int i = 0; i < 100 ; i++) {
        total = total + i;
    }
    System.out.println("------------" + Thread.currentThread().getName() + "calling notify" + System.currentTimeMillis());
    this.notify();
   }

) and call notify at last. What happen when its call notify, because no one is waiting?? next question is Main thread is waiting life time or not?? If not then why not waiting.

Below is the code.

public class Test {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        t.setPriority(10);
        t.start();

        System.out.println();
        System.out.println();

        synchronized (t) {
            System.out.println("waiting " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            t.wait();
        }
        System.out.println(t.total);
    }
}

class T extends Thread {
    public int total = 0;
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 100 ; i++) {
                total = total + i;
            }
            System.out.println("------------" + Thread.currentThread().getName() + "calling notify" + System.currentTimeMillis());
            this.notify();
        }
    }
}

Questions: When child thread run first some times program(Main thread) ended/complete successfully or some time Main thread goes for waiting, Why???

Following is the output:

------------Thread-0calling notify1490271423920

waiting main 1490271423921

In this case Main thread is alive.

------------Thread-0calling notify1490272176789
waiting main 1490272176789
4950

In this case Main thread ended successfully. Why its happening??

Thanks.

Upvotes: 0

Views: 58

Answers (2)

nandsito
nandsito

Reputation: 3852

What happen when its call notify, because no one is waiting??

Nothing happens.

next question is Main thread is waiting life time or not?? If not then why not waiting.

Sorry, I didn't understand your question.

Questions: When child thread run first some times program(Main thread) ended/complete successfully or some time Main thread goes for waiting, Why???

If this.notify() is executed before t.wait(), then the main thread will wait forever, hanging the program execution.

By your code design I guess you want, at this speficic order:

  • the main thread to start T thread and wait()
  • then the T thread to run its code and call notify()
  • then main thread to print result and finish

But your code allows a race condition in that the second bullet may start and finish before the first bullet finishes, causing the undesired behavior.

Upvotes: 3

jtahlborn
jtahlborn

Reputation: 53694

There are a number of best practices related to using wait/notify. All of this information is available online. Some key points:

  • use notifyAll unless you really know what you are doing
  • always wait in a loop (spurious wakeups)
  • use an additional "status" variable which reflects the current shared state. notification doesn't reflect any status, it just wakes up others that are waiting.

the last point is most relevant to your current issue. when you notifyAll, you should also set some sort of status which reflects the intent of the notification.

e.g.

 // thread
 sync() {
   done = true;
   notifyAll()
 }

 // main
 sync() {
   while(!done) {
     wait();
   }
 }

Upvotes: 1

Related Questions