aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes questions of threads and synchronizing Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "questions of threads and synchronizing" Watch "questions of threads and synchronizing" New topic
Author

questions of threads and synchronizing

Rachel Glenn
Ranch Hand

Joined: Oct 24, 2012
Posts: 95
I have a few questions on synchronizing...I think once I get these questions resolved, I will have a good handle on ch.9 in the sierra.bates book!!


I see a code example in the book as follows:




1. First, isn't it correct that the above function is the same as:




2. Why is a run() function specified as synchronized (since the run() function is called by the JVM) ? Is that ONLY so that it can call the notify() method?

Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1456
    
    5

Rachel Glenn wrote:...First, isn't it correct that the above function is the same as...

Correct.

Rachel Glenn wrote:Why is a run() function specified as synchronized (since the run() function is called by the JVM) ? Is that ONLY so that it can call the notify() method?

Frankly, I'm not sure why run method is synchronized. It is something like creating a thread class (either by extending Thread or implementing Runnable) and killing its multi-threading functionality (because when run method is synchronized, only one thread can execute run method at a time - which is exactly like invoking run method manually, without creating threads).

Secondly, in general, synchronization is used to prevent multiple threads entering into a common area. You can call notify inside a synchronized block, but its not the only purpose of synchronized block. Besides, in your code, nobody is invoking wait method, so notify method is of no use.

I hope this answers your question.


Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
Rachel Glenn
Ranch Hand

Joined: Oct 24, 2012
Posts: 95
Well the reason I thought the run() methed had a synchronized block in it was so that you would call notify(). But wouldn't it be sufficient then to rewrite the entire method as follows:


It should never block or have to wait at the synchronized(this) line of code, so it serves the purpose of being able to call notify...
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9280
    
  17

Well the example you have provided doesn't use synchronization for a normal use case. As Anayonkar said run method is generally not synchronized. You are right to call notify method you need a synchronized block. I personally would suggest you don't confuse yourself too much with just this example. See other examples of synchronization (and wait-notify although if I remember correctly wait-notify is no longer on the SCJP exam)...


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Rachel Glenn
Ranch Hand

Joined: Oct 24, 2012
Posts: 95
Ankit Garg wrote:Well the example you have provided doesn't use synchronization for a normal use case. As Anayonkar said run method is generally not synchronized. You are right to call notify method you need a synchronized block. I personally would suggest you don't confuse yourself too much with just this example. See other examples of synchronization (and wait-notify although if I remember correctly wait-notify is no longer on the SCJP exam)...


The other part to this example is the following code:



Isn't it correct that when the main function reaches the synchronized(b) line of code, that the ONLY way it will be placed into a waiting state is if some other object has a lock on the object b? Also, is this correct..?

1. If the main function reaches the line of code and no other object has a lock on b, then the code will get a lock on b, and proceed to the statement, and then hit the , where it will wait until a notify is received.

2. If the main function reaches the line of code and the lock object b is taken, then the code will go into a wait state (waiting for the lock on b to be available). Only after the lock becomes available does the code then execute the println code
Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1456
    
    5

Now we are talking

Yes, your understanding is almost correct (and now the synchronized run method makes some sense).

Just few modifications:
1) In your very first code, when the whole run method was synchronized, the outside world would get thread-safe value of 'total'. That is - either value before thread starts, or the value after thread has completed the operation. However, in your second version of code (where synchronized block in inside for loop), 'total' is not thread safe. It is possible that other thread may access 'total' during the ThreadB operation.

2) Due to thread-unsafety mentioned above, in second version of code, 'Hello there' may get printed in between for loop of ThreaB. If complete run method is synchronized, then this won't happen - 'Hello there' will be either printer before the loop, or after complete execution of the loop.

3) You've mentioned the synchronization order properly, but please note that this is not the only possible way. E.g. it is very much possible that ThreadB will enter synchronized block first, will complete the execution, invoke notify, and exit. After this, ThreadA (i.e. main method) enters in synchronized block, prints 'Hello there' and waits.
The problem here is, now, there's nobody to notify ThreaA, and it will keep on waiting infinitely.

This is the exact reason why it is a good practice to invoke wait method in a loop which always checks a condition (deciding whether the thread should start waiting or not).

I hope this helps.
Rachel Glenn
Ranch Hand

Joined: Oct 24, 2012
Posts: 95
Anayonkar Shivalkar wrote:Now we are talking

Yes, your understanding is almost correct (and now the synchronized run method makes some sense).

Just few modifications:
1) In your very first code, when the whole run method was synchronized, the outside world would get thread-safe value of 'total'. That is - either value before thread starts, or the value after thread has completed the operation. However, in your second version of code (where synchronized block in inside for loop), 'total' is not thread safe. It is possible that other thread may access 'total' during the ThreadB operation.

2) Due to thread-unsafety mentioned above, in second version of code, 'Hello there' may get printed in between for loop of ThreaB. If complete run method is synchronized, then this won't happen - 'Hello there' will be either printer before the loop, or after complete execution of the loop.

3) You've mentioned the synchronization order properly, but please note that this is not the only possible way. E.g. it is very much possible that ThreadB will enter synchronized block first, will complete the execution, invoke notify, and exit. After this, ThreadA (i.e. main method) enters in synchronized block, prints 'Hello there' and waits.
The problem here is, now, there's nobody to notify ThreaA, and it will keep on waiting infinitely.

This is the exact reason why it is a good practice to invoke wait method in a loop which always checks a condition (deciding whether the thread should start waiting or not).

I hope this helps.



Yes it helps thank you! Yes I realized in the second version that the entire run function is not synchronized, but I coded it that way just to demonstrate that the run function would have to resort to that in order to call notify.

BUT, just to confirm, when the statement synchronized(b) is reached, the thread executing that statement will check, right then and there, whether it has the lock on b, and if it does not, then it waits for the lock. correct?
Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1456
    
    5

Rachel Glenn wrote:BUT, just to confirm, when the statement synchronized(b) is reached, the thread executing that statement will check, right then and there, whether it has the lock on b, and if it does not, then it waits for the lock. correct?

Logically, yes.

What happens actually is: when a synchronized statement is reached, the thread(say T1) simply tries to acquire the lock on that object.
If the lock is acquired by other thread(say T2), then T1 cannot proceed. Once T2 releases the lock, then T1 will acquire it and proceed.

T1 will not acquire the lock unless T2 releases it.

This is the exact reason while using cocurrent APIs (e.g. ReentrantLock etc.) unlock method should be invoked in finally block (otherwise, if an exception occurs before unlock, the lock will never be available to another thread).
Rachel Glenn
Ranch Hand

Joined: Oct 24, 2012
Posts: 95
Anayonkar Shivalkar wrote:
Rachel Glenn wrote:BUT, just to confirm, when the statement synchronized(b) is reached, the thread executing that statement will check, right then and there, whether it has the lock on b, and if it does not, then it waits for the lock. correct?

Logically, yes.

What happens actually is: when a synchronized statement is reached, the thread(say T1) simply tries to acquire the lock on that object.
If the lock is acquired by other thread(say T2), then T1 cannot proceed. Once T2 releases the lock, then T1 will acquire it and proceed.

T1 will not acquire the lock unless T2 releases it.

This is the exact reason while using cocurrent APIs (e.g. ReentrantLock etc.) unlock method should be invoked in finally block (otherwise, if an exception occurs before unlock, the lock will never be available to another thread).


Thank you! that makes perfect sense!
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: questions of threads and synchronizing
 
Similar Threads
problem with wait()- notify()
problem in understading wait(), notify() from kb6 book ?
Threads and Sync
wait and notify problem from K&B.
notify(); doesn't work?