This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Hi all I am busy going through the Producer Consumer example, but i don't follow the following workings of the code. What i understand is that when a thread enters a synch method it locks that object so that no other thread can enters it,but the following code looks weird.
Here the while loop will never execute because the put() method is called first and the Consumer have to wait until the lock is released,but in the explanation of the tutorial it talks about the get method quote"The code in the get method loops until the Producer has produced a new value", but the Producer calls the put() method first b4 the get method is called by the Consumer." p1.start(); c1.start(); I don't know if my understanding is correct but any help would be appreciated. Thanks cornel (beautified code list -- mfe) [ December 21, 2002: Message edited by: Michael Ernest ]
Well Cornel... I'm not a real specialist in explanations... But I can say this code really works, because I've implemented this in a recent project here at e-Quality Labs. The thing is, when the PUT method runs for the first time, the while loop will not be executed, but it will set the AVAILABLE attribute will be set to TRUE ! And the process will begin... Got it ? Eduardo Mathias e-Quality S.I.
Next time you want to talk about "the Producer Consumer example", it might be helpful to give us a link or something so we have some context. Many people here learned Java from places other than the Java tutorial, so we don't really know what you're talking about unless you tell us. Or unless we spend extra time searching... Anyway - it seems you've misunderstood something, but I'm not sure which part exactly. Initially, the available field in the CubbyHole is false. This means that when the Consumer calls get() it will keep looping and waiting, until available is true. (Unless that had already changed before the Consumer managed to call get(), which is possible.) However when the the Producer calls put() the first time, it will not loop at all - when it gets to the line while (available == true) it will recognize that available is false, and will skip over the while block and execute the code immediately after it - namely, the line available = true Once the notifyAll() is called and the synchronized put() method is exited, the get() method in the other thread will be able to stop looping, since available is now true. Afterwards the two methods will alternate, with one waiting for the other to complete before it can proceed.
There's some cause for confusion with this example, but let's start with your one mistake: the first thread started doesn't always mean it gets the lock first. That's one beauty of thread scheduling you're always at the mercy of whatever is scheduling thread to run, and there is always the possibility, however slight, that "longer" threads can finish before "short" ones, and that threads started later can begin executing sooner. It's good mental preparation to abandon all certainty about what exactly happens next when you set up multiple threads to run concurrently. Thinking this way will help you avoid creating what is called a race condition, a situation that can arise when your program assumes two or more threads will always finish in a pre-determined order. So we have c1 and p1 which are threaded. One or the other gets some CPU time and starts running through its instructions. It gets to the appropriate synchronized method and acquires the lock of the object, which only prohibits other threads from entering any synchronized method in that object. Non-synchronized methods are still fair game, and that rule bites a lot of people the first time around. The wait/notify scheme in this example uses what is called a conditional variable in multithreaded programming. In this scheme, some thread first acquires a lock, then checks some condition that determine whether the thread can perform its work of not. If not, it must wait() in which case it is sent to sleep with the lock. Sounds like bad news. However, the thread manager itself can get this lock and give it to another thread, on the premise that the original thread can't modify it while sleeping. The next thread gets the lock and possibly changes the value the first thread is waiting on (the boolean available). When done, it notifies and exits, making it possible to return the lock the the first thread. Based on the notification, the first thread might be the next thread to run, might not. That should be the case here since there are only two threads are contending for one lock. The consumer in this example should loop twice if it gets to go first and fall straight through if its goes second. Hope this helps
Make visible what, without you, might perhaps never have been seen. - Robert Bresson
Joined: Jan 30, 2000
See, what we need here is a mechanism for one poster to acquire a lock on a thread while they're working on composing their reply, so that the other posters will be blocked from replying until the one poster makes his post and relinquishes the lock. On the plus side though, this way you get a nice spectrum on answers, saying roughly the same thing with increasing level of detail.