• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

consumes no CPU cycles and notifyAll ... again

 
Ronald Wouters
Ranch Hand
Posts: 190
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

there have already been a lot of posts on this issue, but have you considered the following brainstorm:

The instructions for MY lock method state

If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked.

To make it absolutely clear: it is the current thread that should not consume any CPU cycles.

Now, it his been stated over and over again that using notifyAll isn't a good idea, because it wakes up all the threads not just the ones waiting for the specified record.

However, let's consider for a moment who exactly it is that is wasting the CPU here. When notifyAll is called all the waiting threads will first be moved from the Thread.State.WAITING to the Thread.State.BLOCKED state because they have to re-acquire the monitor's lock.
A thread that is in the BLOCKED state does not consume any CPU cycles, so we are still ok so far, even for those threads that were not waiting for the current record !
Each awoken thread, once it has re-acquired the monitor's lock, will then check the waiting condition again (because that should be in a while loop, remember...) and if the condition fails go back to waiting.
So, one could possibly argue that it is the rechecking of the waiting condition what constitutes the wasting of CPU cycles. But is that really the case ? Even if only the threads that were waiting for the current record got woken up, they would all still have to recheck their waiting condition anyway ! Isn't that a waste too ? I don't think so, it is just how things work.

So, to finally get to point that I am trying to make ... who or what is doing the most CPU cycle wasting here ?
It is the Thread Scheduler when it transitions all the waiting threads from the Thread.State.WAITING to the Thread.State.BLOCKED state !!!

So, to conclude, in my opinion, using notifyAll satifies the requirements because it is not the current thread that wastes CPU cycles, it is the scheduler that does most of the wasting ! A fine distinction you could say, but nevertheless a distinction that allows to argue in favor of using notifyAll...

All comments welcome.
 
Anton Golovin
Ranch Hand
Posts: 527
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To make the notifyAll() controversy go away, the alternative is to use monitor queue and call notify() to wake up just one thread. This is a better solution anyway.

Well, Andrew, if I give away too much (or if I make an error), please just delete this code:

Example:



I did not provide the implementation of the methods. I also used one queue for all the records. This solution does not use the while loop as it will not run more than once.

Also, clearly, if you use a lock/unlock method combination, some of this code would go there and you would add the code to actually lock/unlock the record. You should also then use a queue per record.
[ January 06, 2006: Message edited by: Anton Golovin ]
 
Ronald Wouters
Ranch Hand
Posts: 190
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Anton,

as a matter of fact I had already considered using monitor queues although maybe not implemented the way you did. If you look at one of my earlier posts about the hand-over-hand locking example you will see what I mean. One could use standard JDK 5 java.util.concurrent.locks.Condition objects which in mosts cases will be java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject instances, so queues. This also discussed in the SCJD book.
I was just doing some brainstorming about notifyAll and how one could possibly defend its use.

Regards.
 
Anton Golovin
Ranch Hand
Posts: 527
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Didn't read that post, sorry. I used notifyAll() and got 72/80 (could be for other mistakes, though.) Generally, if I had done the monitors, I would have been more in compliance with the requirements. I also used 1.4, not 1.5 (which I have not studied yet.)

Re: Quote on requirements: until record is unlocked.

Also, as I consider the use of multiple queues one per record, something catches my eye: basically, it is up to the running thread, and not to the Java scheduler, to point out what runs next. So basically, if record 1 has ten clients waiting on it and record 2 has 1, and record 1 is currently locked, all of the 10 remaining threads on it will run before record 2 has any threads work on it. This is not an issue in this application, but could be an issue in some other application where computations are more time-consuming. Therefore, I would say a more fair situation would be to use one queue. Well, maybe Andrew, who I think knows better about these things, could put a word in about this.

(The only way control gets back to Java scheduler is when nothing is waiting on a particular record - with multiple queues.)
[ January 07, 2006: Message edited by: Anton Golovin ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic