![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Newbie
Join Date: Nov 2007
Posts: 8
Rep Power: 0
![]() |
Thread waiting.
I'm having a problem making threads wait on one another. What I'm doing is just a very simple program that has two classes, one that takes "sweets" from a bag called the child and another that puts them in called the parent. Now I'm using a boolean to control when they should each wait and that works fine.
The trouble is, I can't get them to restart. The sun toutorial says that notify() and notiftAll() will wake up a method that is allready waiting but they just dont' seem to do anything . The two classes are shown below.class Parent extends Thread
{
// Our thread works on this
public Bag bag;
// Constructor
public Parent(Bag bag)
{
this.bag = bag;
}
// What our thread does
public synchronized void run()
{
while (true)
{
while(bag.avail)
{
try
{
System.out.println("Parent is waiting...");
wait();
}
catch (InterruptedException e)
{
}
}
bag.sweets++;
bag.in++;
bag.avail = true; //change avail to true so that the child won't have to wait
notify();
System.out.println("parent puts in: " + bag.in + " sweets is now = " + bag.sweets);
}
}
}
// The child thread
class Child extends Thread
{
// Our thread works on this
public Bag bag;
// Constructor
public Child(Bag bag)
{
this.bag = bag;
}
// What our thread does
public synchronized void run()
{
while (true)
{
while(!bag.avail)
{
try
{
System.out.println("Child is waiting...");
wait();
}
catch (InterruptedException e)
{
}
}
//System.out.println("child takes out: " + bag.out + " sweets is now = " + bag.sweets);
bag.sweets--;
bag.out++;
bag.avail = false; //change to false so the parent need not wait
notify(); //here's the problem
}
}
}The variables are all in a seperate class called bag. I can get this to work using "busy waiting", by making the threads loop rather than wait. I'm really stuck with this one and I just need a push in the right direction. Thanks all. |
|
|
|
|
|
#2 |
|
Troll
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4
![]() |
Re: Thread waiting.
notify() and wait() are methods of the Object class, which all other classes ultimately inherit from. You can call notify() and wait() on any object.
It is supposed to play out like this Given an object A. A is shared between multiple threads. 1. Thread 1 needs to use A, so it acquires a lock, with a synchronized block (synchronized keyword doesn't just apply to methods). Let's assume the lock is already available, so this occurs instantly. Thread 1 can now safely call methods on and otherwise manipulate object A, because any other thread that attempts to lock object A during this time will block until the lock is released. 2. Thread 1 determines that it needs to wait for more data to arrive/for some event to occur. It calls A.wait(). Not just wait() -- calling wait() would wait() on 'this', which is thread 1. The reason A.wait() is called is because A is the object for which the lock was acquired. Calling wait() releases the lock and says "I don't want it back...YET" 3. Thread 2 comes along. It acquires the lock instantly because thread 1 released it. Some important thing happens, so it calls notify(). A single thread (thread 1 in this case) is no longer waiting. It goes from "don't want it yet" to "done waiting, give me the lock back." When thread 2 gives up the lock, by calling wait() or exiting the synchronized block/method, thread 1 can grab the lock and continue running - right where it left off, and (depending on your implementation and needs) the waiting condition may be assumed to have been met. In your code: You have two run methods, each of which is marked synchronized. This is more or less a shortcut for putting synchronized(this) { } inside the method. As in, instanceOfParent.run() attempts to lock instanceOfParent. instanceOfChild.run() locks instanceOfChild. When you call wait() or notify(), you are implying this.wait() and this.notify(). You are waiting and notifying two separate objects. Neither case throws an exception because each run() method locks this due to the synchronized keyword. Let's say that the initial bag state is that it contains 1 sweet and avail is true. When you call wait() in the Parent class, it will never wake up because notify() will never be reached. In the Child class, one sweet will be removed and avail will be set to false. It will then call notify(), which will notify *the child*. However, no threads are waiting on the child. At the top of the loop, wait() will be called. Both threads are waiting at this point, with no thread to wake them up. An object that needs to be locked is one that is shared between multiple threads. You probably intended to lock 'bag.' You should wrap most of your run() methods in a synchronized(bag) { } block and call bag.wait() and bag.notify(). I can comment further if you want when you get it working. It takes a while to get your head around it.
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270 |
|
|
|
|
|
#3 |
|
Newbie
Join Date: Nov 2007
Posts: 8
Rep Power: 0
![]() |
Re: Thread waiting.
I tryed putting the synchronized(bag) around my run methods and it works
. I think I understand now. Bag is the method that both threads were trying to work on, so I had to call bag.wait() other wise there would be no way to wake a waiting thread up. Wow, seems like it could take some getting used to it but I think I understand. Thank you so much for your help . |
|
|
|
|
|
#4 |
|
Troll
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4
![]() |
Re: Thread waiting.
Thread synchronization and threading itself are very different ways of looking at things. It takes some thinking. Examples help a lot.
This is from a larger resource about threading in C#. The other sections are largely C# specific. However, the 'Wait and Pulse' section should be helpful to you. The example code is in C# of course, but the Java equivalent should be obvious. http://www.albahari.com/threading/pa...Wait_and_Pulse
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270 |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| How to get current thread ID? | myName | C++ | 2 | Jul 6th, 2006 1:52 AM |
| Accessing another thread | BlazingWolf | C# | 2 | Apr 19th, 2006 4:19 PM |
| Thread Handles? | NoSnipeLimit | Delphi | 1 | Mar 20th, 2006 6:25 AM |
| Finding the posts by a particular user in a particular thread. | InfoGeek | Community Announcements and Feedback | 9 | Nov 4th, 2005 2:43 AM |
| Passing array as argument to a thread | Symptom | C | 5 | Sep 30th, 2005 6:52 PM |