Win a copy of Modern JavaScript for the Impatient this week in the Server-Side JavaScript and NodeJS forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

executing Wait()

 
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
commrades,
I would like to have more light shed on me as regards the wait() method in relation to thread programming. From the book that I am using, I think I dont get it quite clear. I want to understand especially the effect of calling this method.
My understanding is as follows (briefly...
You do not have to explicitly call wait() in your program, rather the call to wait() is embeded within a synchronized method or statement block. So when a thread attempts to execute a synchronized block, the object's wait() method is executed (I dont know by who), throwing the requesting thread into the waiting pool where it will stay until notified by a call to notify ( I dont who will call this method either) that the object's lock is now available. It is only there and then that the thread will actually obtain the lock and execute.I am also informed that when the thread is in the waiting pool, it is actually in the ready state, and not in the waiting state.
Please someone check this and feed me more.
Thanks in advance good people,
Herbert.
 
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Herbert,
As you know the public final wait(..) method is defined for each and every object created in Java. This method and public void notify()/notifyAll() together serve some invaluable purpose in Java. Meaning we all know that threads share a object's data. If there is an object created in a program, and if the program creates and starts 2 threads, as long as the 2 threads can have access to this object, then they both can access the internal details of this object and may corrupt the data. currupt in the sense if one thread is setting the instance var with 10, after sometime it may find that someone else has changed that value without its knowledge.
So this is where the locks/synchronization all come into picture. I give you a simple example. You imagine this happens in our real life.
An interesting example. Read on..
You (thread1) are going to a restaurant. It is a special dining Hall/Room of the common restaurant.(sync method of common object). In order to dine in that room you have to wait in a queue (waiting pool for each object) and get the key (lock/monitor) for that room. So you are patiently waiting and your turn comes (notified and also got the lock of the object) and you are about to go the special dinning room (The owner/waiter says you can go now ). Note here that eventhough you got the key for that romm you have to wait for the owner/waiter (thread scheduler selects thread1 for execution) to say 'You can go now'. So now it is your private room and 'no disturbance please..' board is hanging in front of the room. Others can't use your room now. (Other threads can't run the sync method of this object) After you enjoyed your food with your company just before finishing you are taking off the 'no disturbance please' board, signalling that you and your company are about to leave the room. (The thread notifies others through 'notify()'/notifyAll()') In our example, notify() means the waiter thinks you are about to leave and goes out and picks up the next person to dine in that room. We can't say who will come next. It may be the longest waiting person or may be some VIPs who just entered in that waiting queue. (In thread scheduling also we can't say which one of the waiting threads of the waiting pool of the object will be picked up). notifyAll() means, it is asthough the waiter just makes a COMMON ANNOUNCEMENT and whoever is fast-enough /strong-enough to run and grab the key from you. Every body runs for it, but in the running race only one wins and all others again go back to the waiting queue. So the difference bet the notify() and the notifyAll() is in the latter everybody is given equal chance. IT is upto them to grab the key for the spacial room.
Also note that All these come into picture when you specifically want that special room. Otherwise people are always allowed to dine in the ordinary tables without any problem. Simillarly all these locks/unlock comes into picture when a thread wants to execute the sync methods/blocks. They can always run the ordinary non-sync methods without a need for a lock.
There can be one more interesting case. What if you are saying that you are about to leave the room, so the waiter also notified, but you ARE NOT ACTUALLY leaving the room? You are so mischievous that you are not leaving that room at all.
Remember this is exactly the reason why the wait() method is generally surrounded by a while loop rather than a if loop . Which means eventhough the waiter says that the room is about to be free, you are not getting up from your seat until you see for yourself, that the dinning person is in fact coming out of the room. Otherwise you just keep on waiting, you are not running foolishly to grab the key. So this is the reason, when wait is surrounded by the while loop it again checks for the var or whatever condition to become true and if it is true only it comes out of the waiting loop.
--------------------------------------------
So coming back to your post specifically,
1.You do not have to explicitly call wait() in your program, rather the call to wait() is embeded within a synchronized method or statement block.
Each object has instance wait(..) /notify()/notifyAll() methods. When you write wait() inside a method of any class, you are in fact explicitly calling that wait() method. The extra info in this case is , in order to run execute the wait() method of this object, the current running thread who is executing the method which embeds this wait() method has to obtain the lock of that object. There won't be any compile error if you don't put 'synchronized' keyword. Instead there will be a runtime 'IllegalMonitorStateException' will be thrown. wait() means what? you are releasing the lock/key to others right? In order to release the lock you must first posses it before right? logical thinking Imagine in our restaurant example, how can you give the key of that special room if you don't have it with you at all? It is like that.
---------------------------------------------------
2.So when a thread attempts to execute a synchronized block, the object's wait() method is executed (I dont know by who), throwing the requesting thread into the waiting pool
When the currently running thread is about to execute the synchronized method /block the key is obtained first. If the method/block contains a wait() statement then , the currently running thread which executes this sync method/block executes the wait() method of the object also and goes straight to waiting pool.
To compare to our restaurant case, it is asthough, you are so kind person, and you think of others also, so you are coming out of your meal half way itself and letting others to have a chance for that room. Still you are not yet finished your meal. You want to have some more ice-cream/dessert. So you are patiently waiting for the same romm's key as one among other waiting people. What a nice (considerable) person you are?
--------------------------------------------------------
3. where it will stay until notified by a call to notify ( I dont who will call this method either) that the object's lock is now available. It is only there and then that the thread will actually obtain the lock and execute.
So to continue our case, you have just released the lock and are in the waiting state right? Now some other thread is using the common object. (Some other person is using this room).The notify()/notifyAll() of the common object is executed by the current running , which is running one of the sync mehtods of this common object, this therad is notifying others. When it calls the notify()/notifyAll() somehow the JVM pulls all the waiting threads in this 'common waiting for lock' pool who are just waiting for the notification. The inner details I don't know exactly how they are notified.
4. I am also informed that when the thread is in the waiting pool, it is actually in the ready state, and not in the waiting state.
When a thread is waiting for the lock it is in fact in the waiting state not in the ready state. When notifyAll() is called, all the waiting threads are brought out of the waiting for lock state , but only one thread obtains the lock and is in ready state, all others will find the lock is still with someone else and better go back and wait again. (goes back to same waiting pool again )
regds
maha anna

[This message has been edited by maha anna (edited May 16, 2000).]
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
maha,
Thanks for taking the pains to explain so clearly. I beg you to bear with me and clarify further on the following..
In your explanation I quote
--------------
If the method/block contains a wait() statement then , the currently running thread which executes this sync method/block executes the wait() method of the object also and goes straight to waiting pool.
----------------
I see that here you say if the method block conatins a wait() statement. What I want to further understand is in the case of the code below :
synchronized void someMethod(){
//do something
}
where in the sync method does not have an explicit coded call to wait(),what happens?My understanding is that if we have a thread say t1 and we call t1.someMethod(), t1 will not immediately execute in somemethod() because maybe some other thread t2 already has the lock and is executing in this thread. So this call will result in a call to the object's wait() method(which does not appear in someMethod() above) to send it to the waiting pool so that t2 finishes its processing. , yea I am confused here. But how did t1 then execute wait() on this object, since it had to be the owner first, yet we know the real owner is the currently executing t2 ?
Also my understanding is that a thread will acquire the lock to an object atleast twice inorder to execute a sync method.
Please let us discuss this
Thanks,
Herbert.
 
maha anna
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Herbert,
I try to clear your doubts after Maha's work today.
regds
maha anna
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Congratulations Maha!!
Please explain the difference between notify() and notifyAll()
I will wait till the party gets over of course.
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maha,
Great explanation indeed.
Let me take the liberty to answer Shashank's question. Shashank: notify() lets only one thread(nobody knows which one, including thread scheduler) to come and use the sync'ed method. On the other hand notifyall(() just shouts out that the sync'ed method is now free and ready to be used. Then the strongest thread(may be we can call this as thread with high priority?/) comes and occupies (acquires the lock) and starts executing the sync'ed method.
Maha am I getting it correct ???
Now, Maha, question for u: In ur restaurant explanation, u said that the special room is the method with sync and you said that we'll wait in queue to obtain a key for that room. But..But.. can we obtain a lock on a method??? It should be a object right?? .
So can we think of your example like this?? may be the special room is the object and there's a special table inside that room which is the sync'ed method??? Please clarify.
Once again, thanks for creating a peaceful environment in my brain by giving a great example. You know, otherwise, till now all the threads(thoughts) in my brain are so undisciplined that every thread wants to think in its own way about the thread concepts. Now I think they'llwait in the queue .
Prabhu.
 
maha anna
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Herbert Maosa,Prabhu,Shashank Jha,
Maha tried the best to explain it to you . Please read each and every word and try to understand.
When you say your sync instance method DOES NOT have a wait() method, it simply means, once the thread calling the sync method starts executing , then it doesn't give out the lock for others. So selfish thread it is .
<pre>

synchronized void someMethod(){
stmt1;
stmt2;
stmt3;

//see here . No wait(..)/sleep(..)/yield()/or any other waiting conditions
.
.
stmtn;
}

</pre>
From your next paragrapgh I understand that you are pretty much confused. You are confused bet the object and the Thread.Let me try to clear things up. Read this carefully. I am trying to refine the above example (Prabhu. you are right. I come back to you..)
In Java what do we do ?
1. We define a class definition. This is just a blueprint of the vars and methods of the real objects which we are going to create in memory. So let us define a restaurant class named JavaRanchContinental . Let us say it has a var place and a instance method dineInOrdinaryRoom() and a sync method void dineInSpecialRoom() and another method static void dineInVeryVeryVerySpecialRoom(). So we have a class definition (blue print like foll).
<pre>

class JavaRanchContinental {
String place; //This can be anyPlace in the world
void dineInOrdinaryRoom() {}
void dineInSpecialRoom() {}
void dineInVeryVeryVerySpecialRoom() {}
}

</pre>
2. After blueprint is over you try to build restaurants all over the world. One in India, One in Japan, One in USA, One in China...austraillia...add to this. you can build any no of restaurants in any place in the world as long as you have the resources. It is like you can do
new JavaRanchInternational() as long as you have the memory in your system. So now create two objects (restaurants ) like this.
<pre>

class Test {
JavaRanchContinental inIndia = new JavaRanchContinental();
JavaRanchContinental inUSA = new JavaRanchContinental();
JavaRanchContinental inJapan = new JavaRanchContinental();
}

</pre>
3. Now you have the blueprint, built 3 real restaurants (real objects). Assume you have inagurated all your restaurants all over the world and it is open for public to dine in.
4.Read this portion carefully. Each restaurant has a Manager /some other staff also to run the business. Each restaurant has 3 types of rooms.ordinary(1...n)/special(1...n)/veryverySpecial(1...n) rooms. Assume all the resturants have atleast 1 room in each type built already ,to make our discussion easier and clearer. Each Restaurant Manager has been handed over a special key to open the 2nd type specialRoom. The restaurant can have 1.. to n special rooms with different decarations /different taste may be . But the the only one special room key can be used to open any 1...n special rooms The Manager has this key.
5. Now people (public) are threads. The restaurent is common for all. It has a ONLY ONE key/lock in order to use the special room.This key is does not belong to any one particular special room (Prabhu. you got it . This key belong to the Restaurant as a whole and can be used to open any of such special rooms , but once one room is opened, the key is with the person (thread1)dining in the room, and other rooms can't be used since we have ONLY one key per restaurant (object).
6.Other ordinary rooms can be used since they don't need the key. Simillarly there is no restriction is using the special room in another restaurant. At any time the special rooms in the JavaRanchContinental in India as well as the special room in JavaRanchContinental in USA can be used SIMULTANEOUSLY. No problem, since BOTH Managers at India and USA have their own keys to use the special room in their restaurants.
7. Having said that, The JavaRanchContinetal OWNER , whoever OWNS the whole bunch of restaurants all over the world has another key (Class level key used for static sync method), which is used to open ALL the veryverySpecial rooms in ALL the restaurants in all over the world. This owner also has only one such key. This key is used to have a GET_TOGETHER in the 3rd type VERY VERY SPECIAL room. Once the owner anounces a party , get together , then this means none of the special rooms in all the reataurants can be used, but still the ordinary rooms can be used as usual. ( I guess all people fly/travel to the party, and they appoint temp staff to look after the people who come to dine in ordinary rooms not to disappoint them ).
So when the get together party in 3rd type veryveryverySpecial room is going on , others can't use the 2nd type special rooms.
After the party is over, the owner is happpy and all staff fly back and run their business as usual.
Herbert,
I am not sure if you follow this example. I tried best to refine this example to suit the need. Try to co-oeralte this with Class object, thread, ordinat/instance sync/static sync methods.
I give one last try for you. I go straight to your quotes.
From your post
My understanding is that if we have a thread say t1 and we call t1.someMethod(), t1 will not immediately execute in somemethod()
Maha's comments
This is not clear. See in Java each every code is run using a Thread object. For example when the appln is loaded and started the JVM creades a USER THREAD which run the main(String[] args) method. Simillary, the therad which runs the main(String[] args) method also can create sub threads subThread1, subThread2. Which means the corresponding public void run() methods in subThread1 and subThread2 are executed.
if thread is t1 , then in order to execute the sync method in the common object you don't call ti.someMethod() . You are creating thread t1 with new and in the run() method you call the commonObject.syncMethod() got it? See the example below. I didn't compile it. Just wrote to make is visually clear.
<pre>

class HerbertThread extends Thread{
JavaRanchContinental restaurant;
HerbertThread() {
}
HerbertThread(JavaRanchContinental restaurant) {
this.restaurant = restaurant;
}
public void run() {
//restaurant.dineInOrdibnaryRoom();
restaurant.dineInspecialRoom();
//restaurant.dineInVeryVeryVeryspecialRoom();
}
}
class PrabhuThread extends Thread{
JavaRanchContinental restaurant;
PrabhuThread() {
}
PrabhuThread(JavaRanchContinental restaurant) {
this.restaurant = restaurant;
}
public void run() {
//restaurant.dineInOrdibnaryRoom();
restaurant.dineInspecialRoom();
//restaurant.dineInVeryVeryVeryspecialRoom();
}
}
class Test {
public static void main(String[] args) {
JavaRanchContinental commonRestObj = new JavaRanchContinental();
Thread t1 = new HerbertThread(commonRestObj);
Thread t2 = new PrabhuThread(commonRestObj);
t1.start();
t2.start();
}
}

</pre>

From your post :
because maybe some other thread t2 already has the lock and is executing in this thread.
Maha's comments :Almost correct. because someother thread has already got the lock of the object and is executing the sync method
[b]From your post

So this call will result in a call to the object's wait() method(which does not appear in someMethod() above) to send it to the waiting pool so that t2 finishes its processing.
Maha's comments
Each object has a instance wait() method. This call in not called automatically at any time. It has to be invoked by user specifically by explicit wait() statement. when you explicitly write wait() statement int the sync block, only the current thread which runs the sync block is pulled to waiting pool. The final wait() method does the part of releasing the lock of the current object whose sync methods it executes now,pulling the thread over to the wating pool. when you do not put any wait(), the current thread just runs the stmnt1... stmntn in the above sample code and goes to dead state. So if another thread tries to run the sync method, it has to obtain the lock first, and can't get it now, and it is put back to waiting pool by the scheduler. There is no connection bet the wait() inside the sync block of code and the another thread put back to waiting pool. Whether the sync code has a wait() or not does not matter. It is not at all connected to putting the other thread to the waiting pool. I think you are conneting the simillar name wait() and other thread put back to waiting pool.
The wait() code inside the sync block simply means it is for internal use of the currently running thread, which means, when there is a wait() inside the sync block, the currentlt running therad volunteers itself to give a chance to others by putting itself to the waiting pool. if there is no wait(), it simpley means, it doesn't bother others. It's work is first for it like that. So when other threads try to invoke this sync method , the WORK OF PUTTING the other thread back to waitng pool is done by the scheduler/JVM and it is done perfectly, whether there is a wait() code inside the sync method or not.
From your post:
yea I am confused here. But how did t1 then execute wait() on this object, since it had to be the owner first, yet we know the real owner is the currently executing t2 ?
Maha's comments I hope all previous explanation will help you to answer this. (really confused statement..)
From your post:
Also my understanding is that a thread will acquire the lock to an object atleast twice inorder to execute a sync method.
Maha's comments
No. obtaining the object's lock once itself enough to execute the sync method.
Prabhu,
Yes.yor are right. The object's lock is for the object as a whole, not on any sync method basis. I changed our story accordingly. Also I made up the story such that special room means really special. You have real privacy ,no nearby tables in the same room like that. I still maintained the restaurant as the common object, and the restaurant has a only one special key for any of the special rooms, and after getting the key from the manager, you have the real privacy room where you enjoy your special meal with your special person
Does the thread story sound good to you now? Did you read this post?. This is for you also.
Shashank Jha,
Prabhu had explained it. except when notify() is called 'even the thread scheduler doesn't know ' part. I think he means event he thread scheduler doesn't know which onw to pick statically. But it is the thread scheduler who picks up one thread among the all waitng threads in the pool. Just to make it clear.
*************The End ***********************************
I am going to have a very strong coffee now.
regds
maha anna

[This message has been edited by maha anna (edited May 17, 2000).]
 
maha anna
Ranch Hand
Posts: 1467
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okkkkk. Here is the complete code for our story.
You can compile and run and play with it.
regds
maha anna
<pre>
class JavaRanchContinental {
String place;
//This can be anyPlace in the world
void dineInOrdinaryRoom() {
System.out.println(Thread.currentThread().getName()+ "is eating in ordinary room");
}
void dineInSpecialRoom() {
System.out.println(Thread.currentThread().getName()+ "is eating in special room");
}
void dineInVeryVeryVerySpecialRoom() {
System.out.println(Thread.currentThread().getName()+ "Party is going on in VERY VERY VERY SPECIAL room");
}
}

class HerbertThread extends Thread{
JavaRanchContinental restaurant;
HerbertThread() {
}
HerbertThread(JavaRanchContinental restaurant) {
this.restaurant = restaurant;
}
public void run() {
//restaurant.dineInOrdibnaryRoom();
restaurant.dineInSpecialRoom();
//restaurant.dineInVeryVeryVeryspecialRoom();
}
}
class PrabhuThread extends Thread{
JavaRanchContinental restaurant;
PrabhuThread() {
}
PrabhuThread(JavaRanchContinental restaurant) {
this.restaurant = restaurant;
}
public void run() {
//restaurant.dineInOrdibnaryRoom();
restaurant.dineInSpecialRoom();
//restaurant.dineInVeryVeryVeryspecialRoom();
}
}
class Test {
public static void main(String[] args) {
JavaRanchContinental commonRestObj = new JavaRanchContinental();
Thread t1 = new HerbertThread(commonRestObj);
Thread t2 = new PrabhuThread(commonRestObj);
t1.start();
t2.start();
}
}
</pre>
 
Herbert Maosa
Ranch Hand
Posts: 289
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maha,
I do not take your assistance for granted. I have read and reread your lecture on threads and I am very grateful to you. I feel very confident and I think I have understood quite much. I want to say thank you for your ceaseless effort to make me impossible. I think I should just promise you that I will pass any thread question in the exam, as a token a gratitude for your explanations.
Thank you.
Herbert.
 
today's feeble attempt to support the empire
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
    Bookmark Topic Watch Topic
  • New Topic