It seems that candidates are not being penalised for using notifyAll() even though it does go against the "consume no CPU cycles" requirement.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Clivant Yeo
My Personal Website
Originally posted by Clivant Yeo:
i guess you will have to call notify() instead from your unlock() method, cause it will wake only one thread waiting for the lock, instead of every thread waiting for the lock which will cause more threads to run and try to lock the synchronized object. It will be more inefficient this way.
Just my 2 cents
Rgds,
Clivant
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Anton Golovin ([email protected]) SCJP, SCJD, SCBCD, SCWCD, OCEJWSD, SCEA/OCMJEA [JEE certs from Sun/Oracle]
It looks like you are calling notifyAll() from within your lock method (as well as from your unlock method). Is that correct? If so, why are you doing this?
Yes, I am calling the notifyAll() from within my lock and unlock method. By doing that, I just want to wake up those waiting thread. Is there any problem?
Oops, after a second look, I think I made a mistake. I should only put the notifyAll() from within my unlock() method, but NOT in the lock() method. Right?
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Hi Clivant,
quote:
--------------------------------------------------------------------------------
Originally posted by Clivant Yeo:
i guess you will have to call notify() instead from your unlock() method, cause it will wake only one thread waiting for the lock, instead of every thread waiting for the lock which will cause more threads to run and try to lock the synchronized object. It will be more inefficient this way.
Just my 2 cents
Rgds,
Clivant
--------------------------------------------------------------------------------
Most people write their locking code such that they cannot directly replace the call to notifyAll() with a call to notify() - doing so may result in threads remaining in wait state even after the record they are waiting for has been unlocked.
There is at least one solution that will ensure that only the correct thread gets woken up, thereby meeting the requirement that the waiting thread consumes no CPU cycles. However this is considerably more complex than most locking solutions, and may be harder to understand by our fictitious "junior programmer".
This is one area where we have contradictory requirements, and we have to make a design decision as to which way to go about solving it (and then document that decision ).
Regards, Andrew
Clivant Yeo
My Personal Website
Originally posted by Clivant Yeo:
Hi Andrew,
By going by the sequence lock() -> update/delete -> unlock, the first thread to lock the record will not have to wait. The other threads waiting on the record will form a queue for the record. After the first thread finished its job, it will call unlock which contains notify() to notify a thread at the queue to lock the record again. This process is repeated until no threads are waiting for the record, and hence this method is more efficient as to my opinion.
Rgds,
Clivant
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Anton Golovin ([email protected]) SCJP, SCJD, SCBCD, SCWCD, OCEJWSD, SCEA/OCMJEA [JEE certs from Sun/Oracle]
Originally posted by Andrew Monkhouse:
Hi ,
Admitedly the CPU cycles consumed are minimal, and candidates do not appear to be penalised for this. But technically it does go against the instructions.
Clivant's solution where he will have a queue of threads waiting for record 5's lock, and only one of those threads will be woken, will solve this issue (assuming I have read Clivant's solution correctly). The disadvantage is that you have to have queues per record - not a big disadvantage, but it does make the code more complex.
Regards, Andrew
Originally posted by Andrew Monkhouse:
Hi ,
The problem is in the case where you have multiple threads waiting for locks to become available. For this example I am going to have three threads competing for the same lock, but the same rules apply when you have two sets of two threads trying for locks or ...
Regards, Andrew
Hi ,
The problem is in the case where you have multiple threads waiting for locks to become available. For this example I am going to have three threads competing for the same lock, but the same rules apply when you have two sets of two threads trying for locks or ...
code:
Thread A Thread B Thread C
========================= ========================= =========================
Gains synchronized mutex
Blocked state
Blocked state
Locks record 5
Exits synchronized block
Gains synchronized mutex
Fails to lock record 5
Enters wait state
(synchronized mutex released)
Gains synchronized mutex
Fails to lock record 5
Enters wait state
(synchronized mutex released)
Gains synchronized mutex
Unlocks record 5
Calls notifyAll()
Enters Blocked state
Enters Blocked state
Exits synchronized block
Gains synchronized mutex
Locks record 5
Exits synchronized block
Gains synchronized mutex
Fails to lock record 5
Enters wait state
(synchronized mutex released)
In that example, Thread C consumed CPU cycles the second time it attempted (and failed) to get the lock on record 5.
Admitedly the CPU cycles consumed are minimal, and candidates do not appear to be penalised for this. But technically it does go against the instructions.
Clivant's solution where he will have a queue of threads waiting for record 5's lock, and only one of those threads will be woken, will solve this issue (assuming I have read Clivant's solution correctly). The disadvantage is that you have to have queues per record - not a big disadvantage, but it does make the code more complex.
Regards, Andrew
Clivant Yeo
My Personal Website
Can't you resolve this issue very easy by calling notify() instead of notifyAll() in the unlock method ? Agreed, its still not bulletproof, since the record could be locked again by a new thread while the notify() is called and the waiting() thread tries to gain the monitor... but at least only one thread consumed cpu cycles and not all the other waiting threads.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Originally posted by Andrew Monkhouse:
Which brings us back around to the concept of queueing - if you had a queue of threads just waiting on record 2 in the above example, you could have called notify() on that queue, and only woken a thread which really wanted record 2.
SCJP,SCJD,软件设计师<br />Skype:mediumwave<br />QQ:85646604<br /><a href="http://www.yjping.com" target="_blank" rel="nofollow">http://www.yjping.com</a>
Originally posted by Zhong Bo Li:
一定要使用notify,不要用notifyAll。否则会被扣除很多分。
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
SCJP,SCJD,软件设计师<br />Skype:mediumwave<br />QQ:85646604<br /><a href="http://www.yjping.com" target="_blank" rel="nofollow">http://www.yjping.com</a>
No. No. No. No. Changed my mind. Wanna come down. To see this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|