• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Jeanne Boyarsky
  • Ron McLeod
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

wait and notify code

 
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
class Thread31 {
public static void main(String [] args) {
ThreadB b = new ThreadB();

Xyz ob = new Xyz(b);
Thread x = new Thread(ob);

b.setName("Run");
b.start();

x.setName("Jack");
x.start();




synchronized(b) {
try {
System.out.println("Waiting for thread b to finish "+ Thread.currentThread().getName() + " ... ");
b.wait();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}


System.out.println("Total in main thread " + b.total );
}

} } // end of class

class Xyz implements Runnable {
ThreadB obj;
Xyz(ThreadB ob) {
obj = ob;
}

public void run() {
synchronized(obj) {
try {
System.out.println("Waiting for thread b to finish " + Thread.currentThread().getName() + " ... ");
obj.wait();
}
catch(InterruptedException e)
{
System.out.println("Interrupted");
}


System.out.println("Total in Xyz thread " + obj.total );
}

}
}// end of class

class ThreadB extends Thread {
int total;
public void run() {
synchronized(this) {
System.out.println(Thread.currentThread().getName() + " is started" );
for(int i=0;i<100;i++) {
total= total + i;
}
System.out.println(Thread.currentThread().getName() + " is going to sleep" );
try { sleep(5000); } catch(Exception e) { }
notify();
System.out.println(" AFter notify() " );
}
}
}

Q) In above prgm i am trying to create two thread to wait on one object and when notify is called, than only one of the two waiting thread should get active. but when i run this prgm both of the two waiting threads run.

i bit confuse about this code. can anyone explain, what exactly is going on in this code
 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As I saw the code, I would say that it should make the application hang, because there are two threads calling wait() and only one call to notify(), so at least one thread should remain waiting forever... at least one, because there is a chance that notify runs before both calls to wait() (if 'Run' thread started by b instance gets the lock on this object first, it will execute the whole synchronized block, together with sleep() and notify, before main and Jack have a chance to call wait()).

But I run this code on my computer and it executed just as you said - as though the wait() calls were somehow ignored. I even started one additional Xyz-based thread, but it didn't change anything. Frankly speaking, I don't have any idea why. Either we overlook something very obvious, or the wait()/notify() don't behave as specified in the API
[ August 08, 2008: Message edited by: Dariusz Kordonski ]
 
V K Gupta
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thnks 4 reply,

I TRIED BELOW PROGRAM, THREE THREADS WAITING ON SINGLE OBJECT AND NO NOTIFICATION IS USED THIS TIME BUT EVEN THAN, ALL THREE WAITING THREADS GET START RUNNING.........

THIS EXAMPLE IS FROM THE SCJP BOOK.....

class Thread41 extends Thread {
Calculator c;

public Thread41 (Calculator calc) {
c = calc;
}

public void run() {
synchronized(c) {
try {
System.out.println(Thread.currentThread().getName() + " Waiting for calculation ... ");
c.wait();
} catch(InterruptedException e) { }
System.out.println(Thread.currentThread().getName() + " Total is " + c.total);
}
}


public static void main(String []args) {
Calculator calculator = new Calculator();


Thread a = new Thread41(calculator);
a.setName("A");
Thread b = new Thread41(calculator);
b.setName("B");
Thread c = new Thread41(calculator);
c.setName("C");

a.start();
b.start();
c.start();

try { sleep(2000); } catch(InterruptedException e) { System.out.println("Interrupted " ); }
calculator.start();
}
}

class Calculator extends Thread {
int total;
public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total = total + i;
}
System.out.println(" no Notify this time");
//notify();
}
}
}

what's going on in this code ?
 
Master Rancher
Posts: 5109
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The API doc says:

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious
wakeup. While this will rarely occur in practice, applications must guard against it by testing for
the condition that should have caused the thread to be awakened, and continuing to wait if the
condition is not satisfied. In other words, waits should always occur in loops, like this one:
synchronized (obj) {
while (<condition does not hold>
obj.wait(timeout);
... // Perform action appropriate to condition
}


So you need to add code to test if a condition is true.
Seems like wait() is a different kind of yield().
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It appears that when a Thread exits a notifyAll() gets called on it, or some equivalent release.

In your first posted application, here are the sequence of events that happen in the Run thread:

"Run" thread's start() method called
"Run" thread added to "main" thread group's running threads
"Run" gets some unknown native voodoo on it :-)
"Run" thread's run() method called
"Run" thread attains lock for the current instance of itself
"Run" does its work
"Run" notify()s one Thread who is blocked waiting on itself
"Run" releases the lock on itself
"Run" gets some unknown native voodoo on it
"Run" thread's exit() method called
"Run" thread is removed from "main" thread group
"Run" thread may have more unknown native voodoo done on it
"Run" thread appears to have notifyAll() called on itself
"Run" thread dies.

Since you are waiting on a Thread, and the Thread gets notifyAll() called on it when its job is done, all listeners wake up and begin to do their work.
 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

In above prgm i am trying to create two thread to wait on one object and when notify is called, than only one of the two waiting thread should get active. but when i run this prgm both of the two waiting threads run.



I actually have written a code on similar lines as written by Vijay and it is functioning as expected..But i am not able to figure out the change in Vijay's code in order to function on similar lines.

 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Abhijeet Nalawade:


I actually have written a code on similar lines as written by Vijay and it is functioning as expected..But i am not able to figure out the change in Vijay's code in order to function on similar lines.



In your code, you are using a Runnable to run the code, and you are synchronizing on the Runnable, not the Thread - which is what Vijay should be doing.

He should change ThreadB to implement Runnable instead of extending Thread, and start it like you start Internal i1.
 
Dariusz Kordonski
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're right Steve. More specifically, the issue arises, if you synchronize on the Thread object (I left the ThradB class extending thread, but refactored the code to synchronize on an instance of a separate class, not ThreadB - the code worked 'as it should' i.e. hanged). Probably bacause, as Steve explained, notifyAll() (or something similar) is called on a Thread object before the corresponding thread dies.
 
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello

When you call wait on a monitor you release the lock on it


A thread that calls wait()
releases the virtual CPU; at the same time, it releases the lock. It enters a pool of waiting threads,
which is managed by the object whose wait() method got called. Every object has such a pool.
...

 
Thanks tiny ad, for helping me escape the terrible comfort of this chair.
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic