Win a copy of Microservices Testing (Live Project) this week in the Spring forum!

Rob Pearson

+ Follow
since Jun 12, 2003
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Rob Pearson

I've just been following this thread and was interested in the following:

In comparison, for each recNo in a HashMap, the value is a LinkedList of pending lock objects. As each waiting thread is waiting on its own Lock object, in unlock() I just need to notify the next Lock in the list.
The instructions say 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.". Well with notifyAll(), you'll consume a few CPU cycles just to compete for the lock, which is a (slight ) deviation from the requirements.

Very slight, I would say . Also, remember that notify is a bit like volatile. It should work, but sometimes, it just doesn't seem to. I wouldn't risk failing the assignment over it: not a few non-measureable cpu cycles

I was also concerned about the consuming no CPU cycles requirement and was looking at something similar to Philippe's idea, but I haven't convinced myself that its actually required.
One question though, what happens if the record gets deleted while others are waiting to lock it? and then maybe re-used/re-created? On delete, would you remove that record from the hashMap? Can you actually delete an object that you are synchronized on?
I'm trying to nail down my interfaces between db/network/gui and trying to decide how to return results from the db to the gui.
I started with a Room object which knew about the room details (name,date,rate etc) with suitable get/set methods. Having read various posts about making things expandable/generic I decided this may be too specific so moved back to the String array as specified in the assignment interface. This will need some sort of meta-data (or hard coding!) to work out what values are in which position. I'm now looking at a cut-down version of a ResultSet, that implements just a few of the methods in the ResultSet interface, including a (cut-down) ResultSetMetaData.
This would require less changes if the database were to be replaced to a "real" database with, maybe a JDBC driver. Also ResultSets should be familiar to junior programmers, but I'm wondering if it may be too much effort.
What do others think?
I guess this doesn't help with what gets passed from the gui to the db? SQL is definatelty too OTT.
My help doco should be html, text OR within the application as a help system.
Andrew, you said I left the HTML files as standard files on the hard drive. That way my online help system could access them, or the user could use any web browser to access them..
How did your online help system find the files if they weren't in the jar file?

Moreover, our customer has explicitly requested a design that will make future enhancements easier, so there is some justification for making consideration for those future enhancements part of what you do need now.

Hmmm...interesting, my requirements are almost the opposite:

The IT director does not anticipate much reuse of the first Java technology system, but intends to use that system as a learning exercise before going on to a web based system.

So i'm going very YAGNI, but doing things ways I haven't used much before (RMI, FileChannels, Ant, JUnit etc).
Thanks Vikalp,

works fine. The Java Help stuff looks good, but maybe a bit big, and since I didn't write it, I don't fancy including it in my submission.
Jumping to a completely different part of my assignment, I was just playing around with a help system built into the application. I've just constructed a JEditorPane and set its contents:

This works fine, and I've even got a little HyperlinkListener to follow links in the help file. Looks pretty cool.
However, I'm having problems packaging into my runme.jar file
I can change the url to "jar:file:build/runme.jar!/suncertify/Help.html"
and this also works, but this is a hardcoded path to the jar file . Does anyone know how I can get around this?
Mark, Andrew,
Thanks for the comments.
My assignment states:

Your user interface should be designed with the expectation of future functionality enhancements, and it should establish a framework that will support this with minimal disruption to the users when this occurs

What do people think "minimal disruption to the users" could mean? Does this imply they shouldn't need to install a new version (jar file) to get new functionality? Sounds like a good case for using RMI to fetch the GUI from the server, but doesn't that imply dynamic class downloading and require a security manager? My assignment also states:

You must not require the installation of a security manager.
You must provide all classes pre-installed so that no dynamic class downloading occurs.

How have other people handled this?
Thanks Andrew,
Thats what I thought.
I got Max's book last week, and thought the design they adopted had a diagram with multiple instances of the adapter class, but I could only see one getting created in the code. I thought there may be som RMI magic that I missed.
This may be a silly question, but using RMI, is there only ever one instance of the remote class created?
I've got a server that creates an object then binds it in the Registry. I then run a number of instances of my GUI that all do a lookup on the remote object and get passed (I assume) a stub to the remote object. They then call methods on this, but is there always only ever one created? and if not, how do you create multiple? I can see multiple threads running on the remote object, but the constructor only gets called once?
Am I missing something?
Hi Andrew,

Does this mean that every record in the database would then have a read lock applied?

No, I was thinking of something like:

readLock and readUnLock just required to protect calls to read, so they are not around for long.

Do you handle releasing locks if a client dies (or even just shuts down without clearing locks)?

I've noticed a few posts on unreferenced and WeakHashMaps. I was thinking my client just calls a single bookRoom method (using RMI) on my Data adapter class, that runs on the server. This does the lock/modify/unlock routine. I've tried killing the GUI in the middle of this (by adding a sleep in the modify) but the bookRoom always completes, so always releases the lock. Am I missing something? I can't see a problem with this...maybe I need to test more, with the GUI on another machine?

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

Hmmm... may have a point there, I guess the tread will also wake up when a read lock/unlock occurs.
Although as you point out, taken literally, notifyAll will wake all threads! Too scarry I think I might go home!
Thanks for the advice.

But then, if 3 clients all request hotels in Smallville, doesnt that mean that none of them will be able to book a room, since all the records will now have read locks by all the clients?

I was thinking of allowing multiple read locks (say a count that increments and decrements) and then a write lock waiting until the read lock count (for the record of interest) was zero. Haven't actually coded it yet, but thats what I was planning. ie writes will have to wait for reads to finish.
Does anyone know has "real" databases do this? Can anyone point me to any relavent doco (for my own interest, not for thsi assignment).

In the section of code where you handle checking if the room is still available, is it possible to check the other fields for changes as well?

I was considering an initial "show all rooms" query. If an update happened during this, then the GUI could show incorrect (or possibly garbage) data, since its got nothing to validate against. My point about handling booked rooms was that that is simply a case of checking whether that field (owner) is blank or not.
I agree that when its comes to booking a room I can check that the details are as expected, so there's no chance of booking something unexpected. I'm more concerned with the users attempting to sell rooms that don't match the spec because the data is corrupt.
I keep thinking, 80 points... thats a lot of points for a sprinkling of synchronized, one call to wait and a couple notifyAll?
I'm doing URLyBird 1.3.3, and am looking at the issue of "dirty reads". I've read through a number of other posts on this, but not sure if they all apply to my assignment.
I've currently got a Data class that implements the interface provided. This contains a static list of records that are currently locked. The "lock" method synchronizes on this list with the usual sync/wait/notifyAll. I've then got an adapter for the Data class with the lock/update/unlock sequence to book a room.
This all seems fairly straight forward (assuming it works!) considering locking is worth 80 marks out of 400 (GUI's only worth 40). I'm wondering if I'm missing something. What I'm wondering is do I need read locks too?
My adapter find/search method needs to call "find" on the Data class (returns int[]), then call "read" for each int returned to get the room details. ie lots of calls and lots of opportunities for other threads to get in and change data that was identified by "find". If the change was just that the room is now booked, then I can handle that, but what if some other detail has changed? Is SUNs auto testing software going to try this? If I don't lock a record on read, then half way through a read an update could change the rooms details and possibly result in rooms being returned to the GUI that didn't match the search! (In the interface, the update call is passed all the room details so it could easily change details as well as book rooms).
80 points for locking, plus 40 for the Data class itself, I get the feeling they are expecting more. What do others think?
I'm doing 1.3.3 of URLyBird and my unlock is

// Releases the lock on a record.
public void unlock(int recNo) throws RecordNotFoundException;

I've got a question on the lock method:

// Locks a record so that it can only be updated or deleted by this client.
// If the specified record is already locked, the current thread gives up
// the CPU and consumes no CPU cycles until the record is unlocked.
public void lock(int recNo) throws RecordNotFoundException;

I assume this should have some call to wait() in it, but this throws an InterruptedException. Since I can't just declare it as thrown, because that changes the interface, what should I do with it? Re-throw as a RecordNotFoundException? Just ignore it (not sure if I can)? Fall over in a screaming heap and exit the server!
Any thoughts?
G'Day Andrew,
Sorry, but I'm not sure if I agree.
1. In my assignment (URLyBird), they can only filter on Name/Location and not Date, so they will never be able to "try another date?".
2. If they enter a bad name they will get no results; if they enter a good name but there are no rooms available in the last 48 hours they will also get no results; so in this case there is no distinction between good and bad search criteria.
3. If they don't enter any search criteria, ie a "show all", then I don't see the point in showing unavailable rooms (possible waste of bandwidth/cpu/etc depending on volumes).
4. If I did show unavailable rooms, then I'd need to handle the case of the users selecting and attampting to re-book one of these.
Having said all that, I guess either way is probably OK as long as you document why you designed it a particular way. Since I'm still at the design stage (I assume you've finished?), I may completely change my mind once I have something up and running!