This week's book giveaway is in the Clojure forum.
We're giving away four copies of Clojure in Action and have Amit Rathore and Francis Avila on-line!
See this thread for details.
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

regarding synchronization

 
Erum Momin
Ranch Hand
Posts: 32
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,
In this code when the main method calls b.start(), the lock is owned by the synchronized block in the run method of the ThreadB class. And it won't be availbe for the main method to call the synchronized block in main method..... that's what i got from the code below... can anyone explain me how will it work?

class ThreadA
{
public static void main(String [] args)
{
ThreadB b= new ThreadB();
b.start();

synchronized(b)
{
try
{
System.out.println("Waiting for b to complete..");
b.wait(); //1
}
catch(InterruptedException e)
{
}
System.out.println("Total is: " + b.total);
}
}
}

class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this){
for(int i=0; i<100; i++){
total+=i;
}
notify();
}
}
}
 
Henry Wong
author
Marshal
Pie
Posts: 20835
75
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In this code when the main method calls b.start(), the lock is owned by the synchronized block in the run method of the ThreadB class. And it won't be availbe for the main method to call the synchronized block in main method..... that's what i got from the code below... can anyone explain me how will it work?


Basically, you have a race condition. When the start() method is called, a new thread will be created, which does a bunch of startup stuff, then call run(), which in turn, grabs the sync lock. At the same time, the thread that called start() finishes up the process, and returns from start(), and then, grabs the sync lock.

The question is... which thread will get to it first?

Henry
 
Ken Truitt
Ranch Hand
Posts: 124
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The idea is you want the main thread to wait until the B thread (ThreadB?) finishes its calculations and notifies main,
at which point the main thread will print the result. Here there isn't really any need for wait/notify as you could just
have the main thread do it all. I imagine you want some practice with synchronization and wait/notify, though.

You can't make main wait before b.start() for obvious reasons. You could make the *b thread* WAIT in its run()
method until it is *notified* by the MAIN thread, then make the MAIN thread wait until it is notified in the manner
you have coded already. I think that might work.
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

after main calls b.start(), thread b is not automatically executed - only its state is changed from 'NEW' to 'RUNNABLE'.
JVM may at this point suspend main thread end execute b thread, but may still run main thread while b suspended,
and even (on multiprocesor system) may run main thread and b thread simultanously.
You cannot predict what JVM will do. On systems with one procesor JVM usually will still run main thread
and b thread will be suspended .... but this behavoiur is not guaranted !
And because of this there are two scenarios after main thread call b.start():

Scenario 1.
main thread is still running while b is suspended
in this case main thread will obtain lock on b, then print "waiting for b is complete",
then call b.wait() - this call releases lock on 'b' and changes state of main thread to 'WAITING'.
Then (after some time) JVM will run thread 'b' which will enter synchronized(this) block,
obtain lock on b (lock is released) and will execute code in this block, call notify() and will finish.
Call to notofy() will 'wake up' the main thread ... and main thread will print 'total' and finish.

Scenariu 2
main thread is suspended (before entering synchronized block) while b is runing.
In this case thread b will do it's work, call notify() and finish.
Then main thread will 'wake up', enter synchronized block, print "waiting ...",
then call b.wait() and ..... will hang forever at this point, because there will be no other thread
that could call notify() on object b.
 
Erum Momin
Ranch Hand
Posts: 32
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi Ireneusz,

It's much moe clear now.... thak you very much! !
I have one more question... does calling notify() without waking up any waiting process has any side effect?
 
Ireneusz Kordal
Ranch Hand
Posts: 423
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
call to notify has no 'side effects'.
Behaviour is simple - each object has it's own 'internal table' of threads that called wait() on this object.
If you call notify() on this object, JVM looks into this table, takes one and changes his state
from WAITING to RUNNABLE.
This state means 'hey, JVM, you can run this thread later on ..... when you find some spare time for it'.
If JVM do not find any thread in this table - nothing happens.
 
Erum Momin
Ranch Hand
Posts: 32
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ireneusz,
I got it ! good explanation! ! !
Thanks again...
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic