aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes B&S: wait(time) and CPU cycles consumption Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "B&S: wait(time) and CPU cycles consumption" Watch "B&S: wait(time) and CPU cycles consumption" New topic
Author

B&S: wait(time) and CPU cycles consumption

Andy Davey
Greenhorn

Joined: Sep 02, 2004
Posts: 6
Hi everyone,
I have a question concerning whether a thread waking from the Waiting state will necessarily consume CPU cycles.

In my design, I have interpreted the use of record lock cookies to mean that clients are intended to be sent a lock cookie, which they should subsequently use for booking and unlocking requests(i.e. the client should receive the lock cookie, then send it back in booking and unlocking requests).
With this in mind, a situation could arise where a client could lock a record, but then lose connection before they have a chance to execute the unlock request.

For this reason, my lock method checks whether a thread owning a required record lock is still alive. If it is, then the requesting thread enters the wait state. If not, then the requesting thread removes the old lock and proceeds to acquire a new one.

Unfortunately, when testing this approach, I came across the following scenario:
1) Thread A gains a lock on Record X, and exits the synchronized block in the lock method.
2) Thread B enters the lock method's synchronized block and discovers that Thread A owns the required record lock and is still alive, so Thread B enters the Waiting state.
3) Thread A dies (e.g. due to connection loss), without executing any notify calls.
4) Thread B remains in the Waiting state, blissfully unaware that Thread A is dead.

To overcome this, I altered the wait() call to wait(time), so that Thread B will periodically wake up, and attempt to resume in the lock method, by checking the record lock availability and the status of lock owner Thread A.

This works fine in test, but I suspect that it might contravene the assignment requirement that:
"Any attempt to lock a resource that is already locked should cause the current thread to give up the CPU, consuming no CPU cycles until the desired resource becomes available".

In a nutshell, my question is:
Does a thread waking up following a wait(time) call consume CPU cycles by doing so?

Sorry for the lengthy explanation; any help would be greatly appreciated folks!

P.S. I know I could save myself a lot of grief by implementing a 'thin client', but this point is really bugging me
peter wooster
Ranch Hand

Joined: Jun 13, 2004
Posts: 1033
Originally posted by Andy Davey:
Hi everyone,
I have a question concerning whether a thread waking from the Waiting state will necessarily consume CPU cycles.

In my design, I have interpreted the use of record lock cookies to mean that clients are intended to be sent a lock cookie, which they should subsequently use for booking and unlocking requests(i.e. the client should receive the lock cookie, then send it back in booking and unlocking requests).
With this in mind, a situation could arise where a client could lock a record, but then lose connection before they have a chance to execute the unlock request.

For this reason, my lock method checks whether a thread owning a required record lock is still alive. If it is, then the requesting thread enters the wait state. If not, then the requesting thread removes the old lock and proceeds to acquire a new one.

Unfortunately, when testing this approach, I came across the following scenario:
1) Thread A gains a lock on Record X, and exits the synchronized block in the lock method.
2) Thread B enters the lock method's synchronized block and discovers that Thread A owns the required record lock and is still alive, so Thread B enters the Waiting state.
3) Thread A dies (e.g. due to connection loss), without executing any notify calls.
4) Thread B remains in the Waiting state, blissfully unaware that Thread A is dead.

To overcome this, I altered the wait() call to wait(time), so that Thread B will periodically wake up, and attempt to resume in the lock method, by checking the record lock availability and the status of lock owner Thread A.

This works fine in test, but I suspect that it might contravene the assignment requirement that:
"Any attempt to lock a resource that is already locked should cause the current thread to give up the CPU, consuming no CPU cycles until the desired resource becomes available".

In a nutshell, my question is:
Does a thread waking up following a wait(time) call consume CPU cycles by doing so?

Sorry for the lengthy explanation; any help would be greatly appreciated folks!

P.S. I know I could save myself a lot of grief by implementing a 'thin client', but this point is really bugging me


Of course they do use CPU cycles, nothing ever happens on a computer without using a few cycles on some cpu somewhere. The meaning of that phrase in the requirements is that you not use a "busy wait" style of checking, you should use as few cycles as possible. For that reason I use wait() without the timeout, and rely on interrupt to break out. It will still burn a few cycles if you use notifyAll and the wait is waiting for a different record. You could set up a monitor per locked record and then use notify, but that is probably more work than expected.

NB. Others may have different opinions on this. Maybe someone who has passed with full marks on locking could reply.
Andy Davey
Greenhorn

Joined: Sep 02, 2004
Posts: 6
That's great thanks Peter.
I think I'll revamp my code, so that the whole booking procedure (lock/book/unlock) is performed in one call on the server side, to avoid this issue.

Implementing individual monitors for each locked record seems like more trouble than it's worth.

Thanks again.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11526
    
100

Hi Andy,

Sorry to see you go for the thin client solution. But Phil will be happy.

I am especially sorry since the easiest solution to this dilema is a one line sentence in your design decisions document stating that you thought about client death and decided it was out of scope.

Just for information then ...

I am assuming you are using RMI as your network protocol, since if you were using Sockets you would have notification if the socket was closed.

When using RMI, you need to be aware that there is no guarantee about which threads will be used by which clients. It is quite possible that the thread you were monitoring could have died even thought the client was still connected. Or conversely that the thread you were monitoring was still in use, even though the client that locked a record has died.

Take a look at the java.rmi.server.Unreferenced interface - this will give you a much nicer way of handling client death: After the client has died, RMI will call the unreferenced() method, and you can release any outstanding locks in the normal manner, which saves all your timeout issues.

Alternatively you could also use WeakReferences to store your locks, which again would have the locks released after clients die. But that is a little more awkward to work with when also storing cookies (IMHO).

Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Andy Davey
Greenhorn

Joined: Sep 02, 2004
Posts: 6
Originally posted by Andrew Monkhouse:
Hi Andy,

Sorry to see you go for the thin client solution. But Phil will be happy.

I am especially sorry since the easiest solution to this dilema is a one line sentence in your design decisions document stating that you thought about client death and decided it was out of scope.

Just for information then ...

I am assuming you are using RMI as your network protocol, since if you were using Sockets you would have notification if the socket was closed.

When using RMI, you need to be aware that there is no guarantee about which threads will be used by which clients. It is quite possible that the thread you were monitoring could have died even thought the client was still connected. Or conversely that the thread you were monitoring was still in use, even though the client that locked a record has died.

Take a look at the java.rmi.server.Unreferenced interface - this will give you a much nicer way of handling client death: After the client has died, RMI will call the unreferenced() method, and you can release any outstanding locks in the normal manner, which saves all your timeout issues.

Alternatively you could also use WeakReferences to store your locks, which again would have the locks released after clients die. But that is a little more awkward to work with when also storing cookies (IMHO).

Regards, Andrew


Thanks Andrew,
tried your suggested (java.rmi.server.Unreferenced interface) approach with my fat client design, and it worked like a charm! I was wondering if you have any advice on whether or not to alter the default lease value? 10 or 20 minutes seems like quite a long time for a client to have to wait before a record lock is released by a dead client.

Thanks once again for any help.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11526
    
100

Hi Andy,

I usually alter the lease value when I am testing, but then leave the default value alone for deployment. If the customer wants to deploy with a different lease value, then they can set it on the command line.

In general you do not want to have the lease value too low in deployment - a heartbeat message is sent when the lease has half expired, so if you have a large number of clients connected, you would be generating a lot of heartbeat messages. And their only value is for the (rare) circumstance where a client did not shut down cleanly.

Regards, Andrew
Andy Davey
Greenhorn

Joined: Sep 02, 2004
Posts: 6
Originally posted by Andrew Monkhouse:
Hi Andy,

I usually alter the lease value when I am testing, but then leave the default value alone for deployment. If the customer wants to deploy with a different lease value, then they can set it on the command line.

In general you do not want to have the lease value too low in deployment - a heartbeat message is sent when the lease has half expired, so if you have a large number of clients connected, you would be generating a lot of heartbeat messages. And their only value is for the (rare) circumstance where a client did not shut down cleanly.

Regards, Andrew


Thanks a lot Andrew,
I'll follow your lead on this. Thanks once again for your help,
Andy
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: B&S: wait(time) and CPU cycles consumption