• 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

Confused about Thread synchronization

 
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think that I am ever clear about Thread synchronization.
A code snippet from Page 529 of Sierra and Bates:

I am really confused about line 7 and 8.
In line 7, the main method says that it is "Waiting for b to complete", and then in line 8, the main method says

b.wait();
So, who the heck is waiting? The main or b? Line 8 seems to be saying "Let b wait" and this conflicts with what the main says in Line 7.
Please shed some light on me. Thanks.
Gene
[ September 05, 2003: Message edited by: Gene Chao ]
 
Mark Lau
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It seems that my understanding of the wait() method is contrary to what it really is.
It looks like when ThreadA calls b.wait(), ThreadA is really saying, "little b, go ahead and finish your job, I will be here waiting for you. Let me know when you are done.".
Is this right?
[ September 05, 2003: Message edited by: Gene Chao ]
 
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Gene
I am afraid not. b.wait() means the thread b is waiting.
You can use the join() method in case you wish that thread threadA should wait for thread b to finish its work and then intimate thread threadA when done.
wait(), notify() and notifyAll() are defined in the Object class. Join() method is defined in the Thread class.
 
Mark Lau
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


I am afraid not. b.wait() means the thread b is waiting.


Then would you please explain Line 7 and Line 8? Thanks.


You can use the join() method in case you wish that thread threadA should wait for thread b to finish its work and then intimate thread threadA when done.


Yes, this I understand
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry, but b.wait() means that the CALLER (here, a) should wait until someone calls b.notify(). You don't show the code for b, but presumably the run() method in the ThreadB class calls notify() -- otherwise "a" would wait forever.
The object you call wait() on is used as a kind of "message board;" the word people usually use is "monitor."
 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Gene
Can you paste the full code.
 
Mark Lau
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK, here is the full code.


Sorry, but b.wait() means that the CALLER (here, a) should wait until someone calls b.notify(). You don't show the code for b, but presumably the run() method in the ThreadB class calls notify() -- otherwise "a" would wait forever.
The object you call wait() on is used as a kind of "message board;" the word people usually use is "monitor."


So ThreadA is actually saying, Little b, go ahead and finish your job, I'll be here waiting until get notified.
But then, join() also works like this, the only difference is that you don't wait for any notification. So please explain any other differences between wait() and join().
Thanks a lot.
Gene
[ September 05, 2003: Message edited by: Gene Chao ]
 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ernest
I don't seem to ge it. In this code threadA will wait for B, but that is I guess because b itself is waiting. I mean b is waiting because of a wait() method invocation and threadA is waiting because of b is waiting. Do I make sense? Please clarify.
 
Mark Lau
Ranch Hand
Posts: 120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Anupam, I don't think your understanding of b.wait() is right. Earnest is right and I am probably right, too.
I think I can prove this. Please read.
Run the following code:

And the printout will be Total is 0. This is because the main of ThreadA does not wait until ThreadB finishes.
Run the following code and you'll get Total is 5050.

And this is because b.join() forces the main of ThreadA to wait until b finishes its job.
Run the following code, and you'll also get what you expect: Total is 5050

And this is because you put the main of ThreadA to sleep for 5 seconds,and during this time, b has finished its job.
Interesting, isn't it?
So, what's the difference between wait() and join()?
Gene
[ September 05, 2003: Message edited by: Gene Chao ]
 
Anupam Sinha
Ranch Hand
Posts: 1090
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Gene
Now I also think that my understanding of the wait() method may not be right.
In the intial code you posted the one with b.wait(). I still don't understand which thread is going into the wait state. Try commenting out the notify staatement and see the result.
I must say that it's really a nice question.
Waiting for a nice answer to my queries as well.
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you comment out the notify() in the case where A called wait(), then nothing will ever be printed, and the program won't exit; wait() will never return.
If you call wait() on any object (wait() is a member of Object, not of Thread; Thread just inherits it from Object) then wait() won't return until some code, somewhere, calls notify() on that same object (there are a few details and exceptions that we won't worry about right now.)
If you call join() on a Thread object (it's member of Thread) then join() won't return to the caller until that thread has terminated; so join() means what Gene was saying about "Go ahead little thread, I'll just wait here for you "
I guess the reason this example is confusing is because it's mixing up several concepts at once. Frankly, I can't recall anybody ever calling wait() on a Thread object before; there's nothing wrong with it, there's just usually some other object to call it on that's better.
 
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Gene,
1. Every object has a lock and a wait set. A wait set is a set of threads.
2. x.wait() means add this thread to the wait set of the object referenced by x.

3. x.notify means select and remove a thread from the wait set of the object referenced by x.
synchronized(b)
The main thread acquires the lock of the ThreadB object
b.wait();
The main thread is added to the wait set of the ThreadB object and releases the lock of the ThreadB object.
synchronized(this)
thread-1 managed by the ThreadB object acquires the lock of the ThreadB object.
notify()
The main thread is removed from the wait set of the ThreadB object. When thread-1 releases the lock of the ThreadB object, the main thread acquires the lock and returns from wait().
[ September 05, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Gene, caution.
If the main thread wants to wait for thread-1, it does Not have to acquire the lock of the thread-1 object and invoke wait on the thread-1 object.
The main thread and thread-1 can use Any object. If you don't feel creative, just do this: Object obj = new Object(); and synchronized(obj) and obj.wait() and obj.notify()
Since the virtual machine uses the Thread object to manage the thread, maybe it is Better for the main thread and thread-1 to use some other object.
[ September 05, 2003: Message edited by: Marlene Miller ]
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Line 8 seems to be saying "Let b wait" and this conflicts with what the main says in Line 7.

No, line 8 says �Let the thread that is executing this code wait�. b refers to the object that has the wait set.

It looks like when ThreadA calls b.wait(), ThreadA is really saying, "little b, go ahead and finish your job, I will be here waiting for you. Let me know when you are done.". Is this right?

No, the main thread is saying, �virtual machine, add me to the wait set of the object that little b is pointing to. Some other thread will remove me from the wait set.� Meanwhile, the other thread is executing the run method.
It's unfortunate that in this example little b is related to the other thread.
[ September 05, 2003: Message edited by: Marlene Miller ]
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In this code I don't understand why line 5. is executed before line D.
In this way
b is locked first
then b.wait() gets called
b is unlocked now
then
D. synchronized(this) {
makes b locked again
then
notify()
removes the lock from b again
and main can finish
BUT
if
4. b.start();
executes
D. synchronized(this) {
b is first locked, then a call to notify() and
then b will be unlocked
while main thread will be waiting since
it then executes
b.wait()
a no other thread calls notify on b
1. class ThreadA
2. { public static void main(String [] args)
3 { ThreadB b = new ThreadB();
4. b.start();
5. synchronized(b)
6. { try
7. { System.out.println("Waiting for b to complete...");
8. b.wait();
9. }
10. catch(InterruptedException ie) {}
11. }
12. System.out.println("Total is: " + b.total);
13. }
14.}
A.class ThreadB extends Thread{
B.int total;
C.public void run() {
D. synchronized(this) {
E. for(int i=0; i<=100; i++)
F. { total += i; }
G. notify();
H. }
I. }
L.}
 
Marlene Miller
Ranch Hand
Posts: 1392
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Leonardo, You have described the sequence of events in two ways depending on which thread acquires the lock of the object first. Either way could happen when the program is run.
After the main thread starts the other thread, what happens next depends on the thread scheduler.
If you add Thread.yield() between 4 and 5 and test the program, you might see line D executed before line 5.
4. b.start();
Thread.yield(); // hint to scheduler to run another thread instead of this one
5. synchronized(b)
[ September 07, 2003: Message edited by: Marlene Miller ]
 
Ranch Hand
Posts: 133
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Correct me If I'm wrong. In the above example there is a possiblity that ThreadB can call notify before main has called a wait() on it. In that scenario, main can wait forever.
Please reply soon.
Thanks.
Deep
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic