Rachel Glenn wrote:...First, isn't it correct that the above function is the same as...
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?
Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
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)...
Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
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.
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?
Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
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).
Did you see how Paul cut 87% off of his electric heat bill with 82 watts of micro heaters? |