• 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
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Thread Communication using wait() and notify()

 
Ranch Hand
Posts: 138
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Ranchers!

I have some doubts about the Thread communication using the wait and notify().

Suppose, I have Operator class which accepts size for Cutting the cloths through machine and Machine class which cuts the cloths according to the specified size.

Please consider the bellow code files for both Operator and Machine Class:


and


when i execute the Operator class, i want the output (println statement) should be printed in sequence 1,2,3,4,5,6.
But i have not got the output in the above mentioned sequence.

It is printing something like 1,2,3,1,2,3,1,2,3,4,5,1,6 etc. So, obviously the Size provided by user is overwrite next time when it runs in loops and the Machine will never get that overwritten value for cutting the cloths.

So, can you please provide some solutions and detailed explanation for how can operator wait after providing the size and machine will process the size during that time ?

Any reply is highly appreciated.

Thanks,

Rahul



 
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rahul : Here is a modified version of your code. The main thing to notice is that
both threads synchronize on the same instance of a lock object. Also since the
threads have to wait on eachother, each must wait() and each must notify(). The
Operator instance, when notified, does its work only if ready is false. Similarly,
Machine, when notified, fires up to work only if ready is true. This is the common
wait/notify construct; placed in code synchronized on the same object; checking
and changing a condition flag. Jim ... ...
 
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jim Hoglund wrote:Rahul : Here is a modified version of your code. The main thing to notice is that both threads synchronize on the same instance of a lock object. Also since the threads have to wait on each other, each must wait() and each must notify(). The Operator instance, when notified, does its work only if ready is false. Similarly, Machine, when notified, fires up to work only if ready is true. This is the common wait/notify construct; placed in code synchronized on the same object; checking and changing a condition flag.

Jim ... ...



There are quite a few issues with this code.. specifically...

1. The synchronization is within the while loop. Basically, it is possible for a notification to be send after the lock is released, and before the lock is reacquired in the next iteration of the loop. If this happens the notification will be lost.

2. The while loop and if true/false construct is basically a spin wait, if the condition fails. The code will be spinning for the state -- and not using the wait() method to wait.

3. There is absolutely no reason to use the notifyAll() method here, as you need only one thread to be waken.


Anyway... try...



Henry
 
Rahul Nair
Ranch Hand
Posts: 138
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I understand the changes i need to do.

The things we have to keep in mind for thread communication is that:

1. Both threads have to acquire lock on same instance.
2. Both threads have to wait for each others work to complete.

Thanks for your suggestions!

Rahul
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rahul : Thanks for responding and good luck with your project.
Henry : A bit more on the technical stuff. The while() loop models the business process and
I let it do double duty knowing that Operator won't get the lock unless the condition is false.
But as you point out, this defeats the purpose of the condition flag. I used notifyAll() just
to allow for multiple listeners. [Note to self; must wait() while(condition) not if(condition).]
Thanks and have a good week.

Jim ... ...
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rahul Nair wrote:
I understand the changes i need to do.

The things we have to keep in mind for thread communication is that:

1. Both threads have to acquire lock on same instance.
2. Both threads have to wait for each others work to complete.



Here are some other suggestions, that you may not have noticed from the code (from Jim and I)...

1. Never perform a wait without being about to check the state. Notice that Jim added a state flag? A blind wait is silly, as you don't know if you even need to perform the wait.

2. Never assume the state to wait. Notice that I checked before I performed the wait. It is silly to call the wait() method, when the state is already what you need.

3. Never assume the state upon return from wait. Notice that the check is in a while loop. It is possible for the state to still be wrong upon return, so don't assume.

Henry
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jim Hoglund wrote:
Henry : A bit more on the technical stuff. The while() loop models the business process and
I let it do double duty knowing that Operator won't get the lock unless the condition is false.
But as you point out, this defeats the purpose of the condition flag. I used notifyAll() just
to allow for multiple listeners. [Note to self; must wait() while(condition) not if(condition).]



Multiple listeners actually don't change anything in this case. This is because only one listener can grab the state.

If there are multiple listeners, and you use notifyAll(), then the first listener will wake up, grab the state, do its work, change the state, notify, and go back into a wait state. The other listeners will wake up, notice that the state is incorrect, and go back to the wait state. It is still preferred to use notify() over notifyAll().

Henry

 
Jim Hoglund
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My understanding is that if you have multiple waiting threads, each looking for
a different condition, and you use notify(), the one thread you wake up may not
be interested in the current condition; the notify() will be wasted. So you must
use notifyAll() to be sure the desired thread will run. Am I missing something?

Jim ... ....
 
Henry Wong
author
Posts: 23958
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jim Hoglund wrote:My understanding is that if you have multiple waiting threads, each looking for
a different condition, and you use notify(), the one thread you wake up may not
be interested in the current condition; the notify() will be wasted. So you must
use notifyAll() to be sure the desired thread will run. Am I missing something?



I guess the best answer here is ... don't do this. By design, you should have all threads waiting for a condition to be waiting for the same condition. In the example shown, there are only two threads, so it's not an issue. But, in general, you should not have lots of threads waiting for different conditions using the same condition variable.

Of course, this is not always possible. The classic example is of a bounded queue. Threads that need to add elements would need to wait if the queue is full. And threads that need to take elements would need to wait if the queue is empty. And there is only one lock on the queue.

Prior to Java 5, this was an issue. This is because it was not possible to have multiple condition variables sharing the same lock. For this situation, you needed to write your own lock and condition class. Starting with Java 5, a Lock and Condition class was added -- and these classes allowed multiple condition variables to share the same lock.

Henry
 
Jim Hoglund
Ranch Hand
Posts: 525
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks again Henry. Good discussion.

Jim ... ...
 
Aaaaaand ... we're on the march. Stylin. Get with it tiny ad.
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic