Author | Topic: executing Wait() |
Herbert Maosa ranch hand |
posted May 14, 2000 06:24 PM
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... Please someone check this and feed me more. Thanks in advance good people, Herbert.
|
maha anna bartender |
posted May 16, 2000 12:16 AM
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. 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. regds [This message has been edited by maha anna (edited May 16, 2000).]
|
Herbert Maosa ranch hand |
posted May 16, 2000 09:05 AM
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 synchronized void someMethod(){ 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,
|
maha anna bartender |
posted May 16, 2000 11:52 AM
Herbert, I try to clear your doubts after Maha's work today. regds maha anna
|
Shashank Jha greenhorn |
posted May 16, 2000 02:01 PM
Congratulations Maha!! Please explain the difference between notify() and notifyAll() I will wait till the party gets over of course.
|
Prabhu ranch hand |
posted May 17, 2000 07:30 AM
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 bartender |
posted May 17, 2000 02:04 PM
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 .
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).
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
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. Herbert, From your post 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.
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 Maha's comments 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: From your post: Maha's comments Prabhu, Does the thread story sound good to you now? Did you read this post?. This is for you also. Shashank Jha, *************The End *********************************** [This message has been edited by maha anna (edited May 17, 2000).]
|
maha anna bartender |
posted May 17, 2000 03:10 PM
Okkkkk. Here is the complete code for our story. You can compile and run and play with it. regds maha anna
|
Herbert Maosa ranch hand |
posted May 19, 2000 04:35 PM
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.
|
| | |