• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

wait() and notify() example

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I am reading a study guide for the OCJP exam and im trying to get my head round an example they provided to show the use of wait() and notify(). Here is the example:


Im probably wrong but from what I can see there is no guarantee this code will execute correctly since the lock on the b object could be obtained by either of the threads which will block the other.

Here is how I am assuming it works:
- Thread b is started (line 4) which calls the run method of ThreadB in a separate thread of execution.
- The main thread continues and at the same time as the run method in ThreadB which gets a lock on itself (the object b) by entering the synchronisation block (line 20).
- Meanwhile the main thread gets to line 6 but can't enter the synchronisation block because the other thread has a lock on it. So it waits.
- Thread b finishes counting and calls notify (which does nothing now) and exits the synchronisation block freeing up the lock
- Now the main thread can enter the synchronisation block (line 6) and calls wait on thread b which has already finished

Can anyone tell me if this is possible behaviour? Or would the main thread always get to its synchronised block first?
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you're right. In practice the main thread might always get there first, but there's no guarantee according to the specification. If you want to make the test more robust, I'd add a short sleep() before the second thread enters the synch block.

(And if all you wanted to achieve was to make the main thread wait for the other to finish, join() is a better way).
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

David Kay wrote:from what I can see there is no guarantee this code will execute correctly since the lock on the b object could be obtained by either of the threads which will block the other.



You're correct that there's no guarantee it will execute correctly.

If the TA gets to its sync block before TB does, it will be fine. But if TB gets to its sync block first, then in all likelihood it will call notify() before TA calls wait(), which means that once TA does get to wait(), it will be stuck there forever.


Here is how I am assuming it works:
- Thread b is started (line 4) which calls the run method of ThreadB in a separate thread of execution.



Correct.

- The main thread continues and at the same time as the run method in ThreadB



I continues concurrently (i.e., "in parallel", might be "at the same time", might not be) but depending on how many CPUs you have and what the OS's thread scheduling looks like, they might execute simulatenously, or the might be interleaved (Highly unlikely with so little code to execute. Thread time slicing is generally on the scale of a millisecond, and the above code will take a small fraction of a microsecond to execute.), or one might run to completion before the other starts. (All subject to further restrictions imposed by sync/wait/notify, of course.)

which gets a lock on itself (the object b) by entering the synchronisation block (line 20).



If it gets there first, yes. Otherwise it pauses until TA calls wait().

- Meanwhile the main thread gets to line 6 but can't enter the synchronisation block because the other thread has a lock on it. So it waits.



That's the part that makes this a bad example. We can't predict whether TA will hit its sync block before or after TB does, but correct execution relies on TA getting there first.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Brown wrote:If you want to make the test more robust, I'd add a short sleep() before the second thread enters the synch block.



While that will probably make it work correctly in Long.MAX_VALUE - 1 out of Long.MAX_VALUE cases, that's not guaranteed either.

The correct way (using these low-level idioms) involves waiting in a loop, and checking a shared variable (just a boolean flag will work here). It's been a while, so I'd have to think about it to get it right, and I don't feel like doing that just now.

Now that we have java.util.concurrent though, a simple CountdownLatch will be sufficient to make sure that TB doesn't get to go past a certain point until TA says it can.
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jeff Verdegan wrote:... and I don't feel like doing that just now.



because...

Now that we have java.util.concurrent...



In other words, "Now that I have this handy chain-saw, I don't really remember how to chop down a tree with a stone ax anymore." Unfortunately I don't think that wait() and notify() are going to be deprecated for quite a while, so people are still going to have to learn them in order to pass the exams.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Jeff Verdegan wrote:... and I don't feel like doing that just now.



because...

Now that we have java.util.concurrent...



In other words, "Now that I have this handy chain-saw, I don't really remember how to chop down a tree with a stone ax anymore." Unfortunately I don't think that wait() and notify() are going to be deprecated for quite a while, so people are still going to have to learn them in order to pass the exams.



Oh, I absolutely agree! Just as CS students have to learn to write their own linked lists and merge sorts and what not, I think it's important for Java newbies to learn about the primal multithreading constructs before moving on to the fancy new bells and whistles.

As for me, well, yeah, I don't remember it off the top of my head, but I could figure it out again if I had to. And I could chop down that tree with the stone axe and then beat you at arm wrestling too! So there!
 
David Kay
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the clarification and quick responses. You would have thought a published study guide for the exam would make their examples more robust, especially for a complex subject like concurrency. Oh well, im pretty sure I have the hang of it now.
 
Sheriff
Posts: 3837
66
Netbeans IDE Oracle Firefox Browser
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe you could try to report your findings? It would be useful to rectify such error in study materials.

And, by the way, welcome to the Ranch
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic