wood burning stoves 2.0*
The moose likes Threads and Synchronization and the fly likes Understanding Wait and Notify Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Understanding Wait and Notify" Watch "Understanding Wait and Notify" New topic
Author

Understanding Wait and Notify

Barry Andrews
Ranch Hand

Joined: Sep 05, 2000
Posts: 523

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).]
Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
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

Joined: Sep 05, 2000
Posts: 523

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

Joined: Sep 19, 2000
Posts: 221
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

Joined: Sep 05, 2000
Posts: 523

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

Joined: Sep 19, 2000
Posts: 221
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.
prasanthi kothapa
Ranch Hand

Joined: Oct 19, 2000
Posts: 30
hi Jerry,
what changes do we need to make to synchronize on the
same object.
please explain..
prasanthi
Jerry Pulley
Ranch Hand

Joined: Sep 19, 2000
Posts: 221
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
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Understanding Wait and Notify