Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Mar 6th, 2008, 7:42 AM   #1
equinox
Newbie
 
Join Date: Nov 2007
Posts: 8
Rep Power: 0 equinox is on a distinguished road
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.
equinox is offline   Reply With Quote
Old Mar 6th, 2008, 5:43 PM   #2
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 730
Rep Power: 4 Dameon is on a distinguished road
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
Dameon is offline   Reply With Quote
Old Mar 7th, 2008, 2:56 PM   #3
equinox
Newbie
 
Join Date: Nov 2007
Posts: 8
Rep Power: 0 equinox is on a distinguished road
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 .
equinox is offline   Reply With Quote
Old Mar 7th, 2008, 5:51 PM   #4
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 730
Rep Power: 4 Dameon is on a distinguished road
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
Dameon is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

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




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:47 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC