• 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
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

Understanding Wait and Notify

 
Ranch Hand
Posts: 529
C++ Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In an effort to understand wait() and notify(), I wrote this simple code, but it does not work the way I thought it would. I thought it would print "Thread A is being executed" and then "Thread B is being executed" back and forth until I killed the program, however all that is happening is that Thread B is being executed, and Thread A seems to never get notified so it never runs. Can someone please help me with this? Thanks!!!

[Hope this helps]
[This message has been edited by Rahul Mahindrakar (edited November 05, 2000).]
 
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barry,
If you'll reformat the code so it's readable, I'll be glad to take a look. Just place the tags < pre>< code> before your code and < /code>< /pre> after it. Don't include the spaces, I just put them there so they wouldn't get parsed as HTML in this message.
jply
 
Barry Andrews
Ranch Hand
Posts: 529
C++ Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is the code:
<pre><code>
public class TestAB implements Runnable
{
Thread threadA;

TestAB()
{
threadA = new Thread(this);
threadA.start();
}

public synchronized void run()
{
while (true)
{
System.out.println("Thread A is being executed");
try
{
wait();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}

class AnotherClass implements Runnable
{
Thread threadB;

AnotherClass()
{
threadB = new Thread(this);
threadB.start();
}


public synchronized void run()
{
while (true)
{
System.out.println("Thread B is being executed");
notify();
}
}

public static void main(String[] args)
{
AnotherClass b = new AnotherClass();
TestAB a = new TestAB();
}
}
</code></pre>
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barry,
Two changes and it'll give the behavior you're looking for.
1)Thread B never waits. Give B a call to <code>wait</code> like A has, and give A a call to <code>notify</code>. Both threads need to issue a notification then wait. Of course, you'll want some way to control which one goes first, so they both don't end up waiting for the other to notify them.
2)The threads need to synchronize on the same object. <code>wait</code> and <code>notify</code> are methods of <code>Object</code> - <code>wait</code> sends the current thread to the monitor object's wait set and <code>notify</code> wakes one thread from that wait set. Currently, Thread A syncs on the instance of <code>TestAB</code> and Thread B on the instance of <code>AnotherClass</code>, so the threads are in different wait sets.
jply
 
Barry Andrews
Ranch Hand
Posts: 529
C++ Java Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jerry,
I am not understanding why both synchronized methods would need to call wait() and notify(). Could you expain a little more please? Also, how would I go about controlling which one goes first so they do not get deadlocked? Thanks!!
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Barry,
Both threads need to wait (and notify the other just before waiting) so they'll run continuously in sequence, one after the other. Thread A starts, prints a line, and waits. Thread B starts, prints a line, notifies A, and waits. A stops waiting (because it got notified), prints a line, notifies B, and waits. B stops waiting (because it got notified), prints a line, notifies A, and waits. And so on.
As to why they've got to sync on the same object - if they each must have that object's lock to run, they can never run at the same time.
If you don't care which one goes first, just start them. If it matters, place a flag in A's Runnable which is initialized to true. If the flag is true, A sets the flag to false, notifies then waits right away. The flag is never touched again.
 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi Jerry,
what changes do we need to make to synchronize on the
same object.
please explain..
prasanthi
 
Jerry Pulley
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
First, a little more on wait sets, notification, monitors, etc. (If you already know this stuff, bear with me.) In Java, any object can act as a monitor - that's an entity with a single lock and a wait set.
When an object's <code>wait</code> method is executed, the currently executing thread enters that object's wait set. As long as it's there, it sits idle.
When an object's <code>notify</code> or <code>notifyAll</code> method is called, one or all of the threads in its wait set are removed from the set. They then actively contend for the object's lock, and the one that gets the lock goes on to execute.
In the situation here, we want only one of the threads to execute at one time. The easy way to do this is to arrange for one of them to be in an object's wait set and the other to be executing, and have them change places periodically. They change places when the executing thread calls the object's <code>notify</code> method (so the other one leaves the wait set) and then calls the object's <code>wait</code> method. When the executing thread enters the wait set, it gives up the lock (which is grabbed by the newly awakened thread, which can then execute) and takes the other one's place in the wait set. Voila! The threads have changed places.
There are lots of ways to arrange this behavior in code; here's one that makes what's going on explicit:
  • The outer class no longer implements <code>Runnable</code>. It's the controller, not a thread.
  • Add a field of type <code>Object</code> to the outer class, call it <code>monitor</code>. Initialize it with <code>new Object()</code>.
  • Rename the inner class <code>ClassA</code> and don't synchronize its entire <code>run</code> method. Instead, place the body of its <code>run</code> in a block marked <code>synchronized (monitor) {...}</code>.
  • Create another inner class that also implements <code>Runnable</code>, called <code>ClassB</code>. Move the old <code>run</code> method from the outer class inside <code>ClassB</code>. Enclose its body in <code>synchronized (monitor) {...}</code> just like the other. Now the two are set to sync on the same object.
  • Make sure each <code>run</code> method has a loop that prints its line, calls <code>monitor.notify</code>, then <code>monitor.wait</code>.
  • In <code>main</code>, create threads from the inner classes and start them.

  • You might have to mess with things a little to get it all to work, but that's a fairly general solution for ensuring only one thread can run at once. In a larger program, you might use this arrangement to protect <code>monitor</code> from being accessed by both threads at the same time.
    jply
 
This parrot is no more. It has ceased to be. Now it's a tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic