• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help with Threads, Locks and Conditions  RSS feed

 
Tony Bateman
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have been going through a Java text book, and am currently wrestling with Threads (apt metaphor since I'm getting tied up in knots).

I'm trying to understand the relationship between them and what is really happening at runtime. I have a few questions.

Consider this code snippet:



1) Why does the await() method have to be in a while{} loop? Is the while loop actually running all the time in the thread, constantly invoking the await() method??
2) Isn't it enough that await() is invoked once? (that is assuming the loop is running all the time).
3) How can a ReentrantLock be locked, and yet released by the await() statement, and yet still be locked?

As you can see, this is not at all clear to me.

Could anybody help me understand this?

Also, does anybody have any good material that shows what is happening with Threads, locks and conditions in a graphical manner, in a way that could help consolidate my understanding of this subject?

Much appreciated!

- Tony.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Bateman wrote:
1) Why does the await() method have to be in a while{} loop? Is the while loop actually running all the time in the thread, constantly invoking the await() method??
2) Isn't it enough that await() is invoked once? (that is assuming the loop is running all the time).


You have to remember that you are in a threaded environment. So...

1. Your thread needs some resource in a certain state -- in this case, a free slot in the buffer -- so it waits for it.
2. Later, some other thread frees the resource, and sends the notification.

At this point, your thread should wake up and it should work... however, remember that you are in a threaded environment...

3. A third thread comes along, and also needs the same resource in a certain state. It sees that it is available, and takes it.
4. Your first thread gets the notification, and...

This is why, it is common practice to never assume the state when you return from await on a condition -- because it may still not be in the state that you want.

Tony Bateman wrote:
3) How can a ReentrantLock be locked, and yet released by the await() statement, and yet still be locked?


That is just how it works. The condition await() method will completely release the lock (even if the lock has been acquired many times), and prior to return will reacquire the lock (as many times as it was released). And it also does it in a way so that no notifications are lost.

Henry
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tony Bateman wrote:I'm trying to understand the relationship between them and what is really happening at runtime.

Just to add to Henry's excellent advice: One thing that's quite difficult to "get" when trying to visualise multi-threaded applications is that, in the absence of some kind of locking mechanism or synchronization, two pieces of code - from two different threads - can (and almost invariably do - Sod's Law applies ) access or change the same variable, or call the same method, at exactly the same time.

And these situations are so instantaneous that, for example, in the case of a Thread A writing to a long while Thread B is trying to read it, Thread B can "see" an unfinished update (ie, Thread A has only written half of the new bits to the field), which could be complete gibberish as far as its value is concerned for Thread B.

That's why it's so important for multi-threaded code to always deal with critical data (and that includes locks) from within a controlled area like a try... or synchronized block.

HIH

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Note also that even if you can guarantee that only two threads are contending for the same lock, you still need to await in a loop (as opposed to a simple if statement) because wait() and await() can wake up spuriously, you use them to prevent the while from running continuously, but they don't actually guarantee that a thread will wait until woken up explicitly.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!