aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Using Unreferenced vs a daemon thread 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 "Using Unreferenced vs a daemon thread" Watch "Using Unreferenced vs a daemon thread" New topic
Author

Using Unreferenced vs a daemon thread

HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Posted this on another thread but would like some help with this.

Is using Unreferenced vs a daemon thread to free dead client locks two separate design options or can both be used in conjunction?
That is 1: use Unreferenced and let the "system" decide when to release the lock for the dead client.
2: Don't specify a lease period and the "application" with a daemon thread decides when to release the lock.
If this was the case, personally I'd rather let the "system" handle this , and free the application to do flight search and bookings.
I'm thinking along the lines of the way garbage collection can be handled.
i.e. Leave the JVM to do it by itself, or force the collecion by setting references to null.
regards
[ March 13, 2003: Message edited by: HS Thomas ]
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
How about option 3) -- don't do it! It's not in the requirements, and you will not lose any points if you don't implement the cleaning of crashed clients.
But if you feel compelled to do it, I would say that Unreferenced is the most natural solution, -- let RMI's distributed garbage collector do the work.
Eugene.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Use Unreferenced, it is quick and easy.
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Eugene,
Option 3 is even better.
Mark,
now I feel compelled to use unreferenced at least once. I'm sure I'll never get another opportunity to do so.
Thanks guys.
regards
[ March 14, 2003: Message edited by: HS Thomas ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by HS Thomas:
Option 3 is even better.
While it's not part of the requirements, it's a useful bit of functionality indeed. In my implementation, all I had to add was The unlockAll() method did already exist; it's called from the close() function as well. While optional, nice to have functionality rarely comes as cheaply as this
- Peter
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
While optional, nice to have functionality rarely comes as cheaply as this
.
Peter,
I'll take your esteemed word for it.
That innocuous line of code could be sitting on a powder keg for all I know, waiting to be lit.
If I put it in, I have to test and maintain it . I'd personally rather let the responsibility be someone else's.
Oh OK, just this once.
regards
[ March 14, 2003: Message edited by: HS Thomas ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by HS Thomas:
That innocuous line of code could be sitting on a powder keg for all I know, waiting to be lit.
That's a true word; I guess I was just a little bit too glib there. You're right, whenever you venture into territory you don't know well (and RMI DGC and Unreferenced are unfamiliar territory for many of us, I guess) then seemingly simple code can hide a whole hornets' nest of problems. I guess we all have our tales of thrown-in freebies that turned into support nightmares.
Thanks for adding that necessary bit of perspective
- Peter
[ March 14, 2003: Message edited by: Peter den Haan ]
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
RMI DGC and Unreferenced are unfamiliar territory for many of us, I guess

Peter, I have the UTMOST respect for those who do understand it well.
I guess its fear of the unknown that has the rest of us either stay well away (me) or add a patch hoping it'll give some degree of control.
regards
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

RMI DGC and Unreferenced are unfamiliar territory for many of us, I guess

Yeah, it takes some guts to dive in the details of it. Talking about Unreferenced, I noticed the following in the Garbage Collection of Remote Objects section of the RMI spec:
"Note that if a network partition exists between a client and a remote server object, it is possible that premature collection of the remote object will occur (since the transport might believe that the client crashed). Because of the possibility of premature collection, remote references cannot guarantee referential integrity; in other words, it is always possible that a remote reference may in fact not refer to an existing object. An attempt to use such a reference will generate a RemoteException which must be handled by the application".
In light of this information, my question for the RMI experts is this: "Would implementing the Unreferenced diminish the possible problems in case the premature collection happens, or does it increase the risk of problems?"
Eugene.
[ March 14, 2003: Message edited by: Eugene Kononov ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Just to make it democratic, I'll chime in to disagree here.
You can achieve the same result of freeing 'lost' locks by using a WeakHashMap which maps clients to keys. This weakHashmap would be static, and live as a member of Data.
This is a easier implementation, and has less complexity: thus, IMO, it is more elegant. Admittedly, it is not a significantly large amount of complexity that we're talking about here.

M, author
The Sun Certified Java Developer Exam with J2SE 1.4


Java Regular Expressions
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Hi Max,
Perhaps it will be a good idea if a list of pros and cons on the usage of Unreferenced vs WeakHashMap is drawn up and treat it as another design option to be considered.

Somewhere along the lines of using RMI or Sockets to build the network layer(I agree the decision is not at the same level . Thinking about it , if you are using Sockets to build your network layer you are forced to consider WeakHashMap).
Someone like Eugene or Mark (preferably both) can be chairperson and draw up a definitive list of pros and cons from which any future discussions can be referenced.
Just an idea. Good for democracy.
regards
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Eugene Kononov:

: "Would implementing the Unreferenced diminish the possible problems in case the premature collection happens, or does it increase the risk of problems?"
Eugene.
[ March 14, 2003: Message edited by: Eugene Kononov ]

It seems that you are, in fact, increasing the risk, if slightly so. That is, when you call the object to release it, you are, potentially, risking one more call then strictly necessary to an object that might not exist anymore. Granted, this is a small risk, but an unnecessary one, ISTM.
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
[ March 15, 2003: Message edited by: Max Habibi ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by HS Thomas:
Hi Max,
Someone like Eugene or Mark (preferably both) can be chairperson and draw up a definitive list of pros and cons from which any future discussions can be referenced.
Just an idea. Good for democracy.
regards

It's a good idea. In fact, it's such a good idea, that Mark and I are already doing it . moderating the discussion, and offering differing points of view. It's actually very democratic that we don't share the same point of view on this.
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Hi Max,
Excellent. I've just noticed that you are also moderator of this forum.
I haven't logged on for a while so I've missed the last few postings.
Any chance of a definitive list of pros and cons?
Or is having a good dig around and asking questions all part of the learning process ?
Some of the old postings may not be relevant anymore.
regards
[ March 17, 2003: Message edited by: HS Thomas ]
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
JavaRanch.com - 2002 Jolt Award Finalist

Having said that, know a good thing when you see it.
Don't change ( or not too much).
regards
[ March 18, 2003: Message edited by: HS Thomas ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
It's a great idea, and I'll definitely do so in a bit. But I was hoping to let this thread absorb some more feedback.
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
[ March 17, 2003: Message edited by: Max Habibi ]
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Thanks Max,
Eugene,

posted March 14, 2003 11:22 AM
--------------------------------------------------------------------------------
quote:
--------------------------------------------------------------------------------
RMI DGC and Unreferenced are unfamiliar territory for many of us, I guess
--------------------------------------------------------------------------------

Yeah, it takes some guts to dive in the details of it. Talking about Unreferenced, I noticed the following in the Garbage Collection of Remote Objects section of the RMI spec:
"Note that if a network partition exists between a client and a remote server object, it is possible that premature collection of the remote object will occur (since the transport might believe that the client crashed). Because of the possibility of premature collection, remote references cannot guarantee referential integrity; in other words, it is always possible that a remote reference may in fact not refer to an existing object. An attempt to use such a reference will generate a RemoteException which must be handled by the application".
In light of this information, my question for the RMI experts is this: "Would implementing the Unreferenced diminish the possible problems in case the premature collection happens, or does it increase the risk of problems?"

My impression is that currently in practice, RMI is not considered suitable to be used across network partitions, but is used for applications within the Enterprise.
I use the term Enterprise rather loosely.
Partnerships that share a dedicated link (e.g. a T1 connection ) for a common business purpose, can use RMI.
Also departments that need to share information could use RMI within the Enterprise. I have yet to see that though .That depends on the amount of trust/sense of partnership that exists. Departments may insist on
the other using say Web Service, as yet an untested technology.
That weighed against ease of development and deployment of technologies based around RMI may swing it one way or another. Depends on who is pulling the strings, I guess. So all in all ,it's still worth learning.
It'll be nice to see how RMI stands up to it's challenges and evolves.
I particularly like the Connection, LockManager paradigm , so personally would follow the RMI- Unreferenced track through. It would help to know the limitations though. It gives me a warm feeling to know that I can just fall back on WeakHashMap to get client locks released , assuming this works across a network partition - I believe , here you are relying on the JVM's garbage collection and not the DGC of RMI.
RMI experts , please share some of your experience, so Max and Mark can get on with the pros and cons list.
regards
[ March 18, 2003: Message edited by: HS Thomas ]
[ March 18, 2003: Message edited by: HS Thomas ]
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
Here is a relevant discussion that unfortunately was never settled. Among other things, it covers the Unreferenced vs WeakHashMap issues.
In my opinion, WeakHashMap is best to hold cache, and Unreferenced is best to release the unreferenced objects.
There are some additional considerations:
-- WeakHashMap uses its keys as weak references. That means that your map should be from client to record which is somewhat counterintuitive and it also prevents the client from locking multiple records.
-- The entries of WeakHashMap are not released until the WeakHashMap is altered. If you do not call any mutator methods after populating the WeakHashMap, the values and WeakReference objects will never be dereferenced.
-- Since WeakHashMap wraps its internal HashMap, there may be some significant performance overhead. Every call to get() creates a new WeakReference object to enable equality testing of keys in the internal HashMap. The size() is an operation that takes time proportional to the size of the WeakHashMap, since it has to go through all the records to count those that have not been cleared. isEmpty() iterates through the collection to find a non-null key.
Of course, both WeakHashMap and Unreferenced will do the job and you will pass. However, since Unreferenced is a standard solution to garbage collection in RMI, it seems more appropriate in the context of this assignment. Using WeakHashMap instead of Unreferenced to clean the remote objects in RMI would be like coding your own merge sort instead of using the sort() method in the Collections interface.
Eugene.
[ March 19, 2003: Message edited by: Eugene Kononov ]
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Thanks Eugene for the link and points.
Here's a matrix to prod things along.
I have marked some lines with an asterisk that have only columns blanked as I don't know how RMI compares. Hopefully they will be addressed soon.

regards
[ March 18, 2003: Message edited by: HS Thomas ]
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Sorry, couldn't resist the following :
The weightings are my own. And I can change them as I get better informed/ understand the real world context in which it has to be applied. I keep one for myself and maintain another that my manager has got involved in because he lives on another planet.
A crude but powerful tool, never the less. Puts things in some context as you dig deeper and handle the complexity.

And the same on applying a weighting in context of the assignment

As this debate is on the use of Unreferenced vs WeakHasMap with RMI the following two lines can be reduced to one - | 3 | Best for unreferencing remote objects:


Which reduces the score to 9 - 2 , 5 - 2 in my charts.

Could do with some more feedback, on RMI. Any takers ?
[ March 19, 2003: Message edited by: HS Thomas ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Eugene Kononov:
In light of this information, my question for the RMI experts is this: "Would implementing the Unreferenced diminish the possible problems in case the premature collection happens, or does it increase the risk of problems?"
My understanding is that in this respect it won't make any difference whatsoever. By the time Unreferenced is called, the DGC has already decided that the Remote object is ripe for cleanup, and is engaged in that cleanup process. Once this has been completed, your Remote object will be unavailable whether you implement Unreferenced or not.
Obviously, if you decrease the DGC lease value so that locks get cleaned up sooner, you increase the chance of network glitches producing false DGCs. Is this a reason to prefer independent timers to expire locks? As things stand, not necessarily. Once you've timed out a client's locks, the next database call should produce an exception of some kind; after all, the client still thinks it's got the locks and undefined behaviour might result. Invalidating the entire Connection object -- which is what the DGC action boils down to -- may be crude but seems the simplest way to handle this situation safely.
- Peter
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
While doing some tests on my implementation I found the following issue with unreferenced. If a single client opens 10 threads opening each a different connection on the server database, each connection in a loop takes the lock on the same record as the other threads, modifies the record and releases the lock. When the client disconnects abruptly the server calls the unreferenced() on each connection, only the currently owned lock is freed, notifyAll() is called, and one of the server waiting locks takes the lock but the client is already dead, and the lock is taken and that's it. I am then obliged to take the not very elegant measure of a timeout thread cleaning the lost locks that occurs each at the time. Is there a way to know when a client dies if one of its lock is on a waiting stage?
C.
PS:I hope this is readable.


Charles.<br />(SCJD2)
HS Thomas
Ranch Hand

Joined: May 15, 2002
Posts: 3404
Peter,
In the context of a client handling multiple record locks and as quoted by you here
Invalidating the entire Connection object -- which is what the DGC action boils down to -- may be crude but seems the simplest way to handle this situation safely.

would it be safe to assume that in the rare (?) event of a premature DGC , the entire transaction may be abandoned as though the client itself had deliberately quit ?
Would it also be safe to assume that most transactions can be designed to be completed in the window that the RMI sub-system provides(default lease values ,DGC etc) ?
regards
[ March 19, 2003: Message edited by: HS Thomas ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Charles, you mean that it is possible for a Connection to acquire a lock after unreferenced() has been called on it, if it was wait()ing for that lock when unreferenced was called? Interesting. A very good point that I'd never thought of.
Offhand, I can think of two ways to address this
  • Synchronize lock() and unreferenced() on your Connection object, so as to block the unreferenced() call while a lock is under way. I'd want to take a very careful look at potential issues with deadlocks and DGC operation before I did this, though.
  • Maintain a boolean instance variable "closed" on Connection, which would be set by both close() and unreferenced(). Have LockManager check this right before it wants to grant the lock. If the Connection is closed, throw an exception or simply return w/o lock.
  • These are both impromptu ideas, so they might be misguided.
    Max' WeakHashMap solution acts only later, when the object is getting garbage collected, and therefore doesn't have this problem
    - Peter
    [ March 19, 2003: Message edited by: Peter den Haan ]
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Thomas, I'd think yes in both cases. The "transaction" is not a true transaction of course; we're not in a position to roll anything back...
    - Peter
    Charles Dupin
    Ranch Hand

    Joined: Oct 18, 2002
    Posts: 94
    Peter,
    For the unreferenced issue of the wait()(ing) locks, I prefer the flag solution. Just set the flag at the entry of the unreferenced() method.
    Charles.
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404
    Peter,
    Thanks. I asked this with DBMSs in mind.Some DBAs advise treating rollbacks with caution as they can be expensive. So there may not be that many multiple transactional updates required/allowed. But woe for any DBMS that doesn't support them.
    Can I say the same for the Network layer ?
    I am beginning to understand and respect the "limiting" scope of the assignment.

    Equal scores ? ( The weightings are my own )
    Any light on performance overhead that comes with Unreferenced ?
    regards
    [ March 24, 2003: Message edited by: HS Thomas ]
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404
    Would
    Invalidating the entire Connection object -- which is what the DGC action boils down to

    and
    Maintain a boolean instance variable "closed" on Connection, which would be set by both close() and unreferenced(). Have LockManager check this right before it wants to grant the lock. If the Connection is closed, throw an exception or simply return w/o lock.

    ensure that client locks will always dereference safely, whereas WeakHashMaps may never dereference under conditions quoted in :

    -- The entries of WeakHashMap are not released until the WeakHashMap is altered. If you do not call any mutator methods after populating the WeakHashMap, the values and WeakReference objects will never be dereferenced.

    regards
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Originally posted by HS Thomas:
    Any light on performance overhead that comes with Unreferenced ?
    None whatsoever. The RMI DGC will have a bit of code somewhere that saysOr equivalent. WeakHashMaps, on the other hand, carry some performance penalty in reference traversal and management -- I can't recall having seen benchmarks though.
    Compared to WeakHashMap, Unreferenced-based cleanup is both better guaranteed and quicker. Also cleaned-up locks are immediately available to threads waiting for them.
    - Peter
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404
    The outcome for me is that Unreferenced comes ahead . I've tried to be fair and given the same weightings for like issues. e.g 2 for DGC and SSGC but will still be biased towards my preference for a solution that fits in with Connection - LockManager - RMI.
    A design that was detached from RMI could well apply different weightings and additional nice-to-haves to strengthen the design.(e.g a 0 weighting for invoking the DGC and a nice-to-have daemon thread in addition to server side GC).
    A crude way of gaining some rationality , but still useful.

    Max Habibi
    town drunk
    ( and author)
    Sheriff

    Joined: Jun 27, 2002
    Posts: 4118
    /**
    Originally posted by Eugene Kononov:
    There are some additional considerations:
    -- WeakHashMap uses its keys as weak references. That means that your map should be from client to record which is somewhat counterintuitive and it also prevents the client from locking multiple records.

    Not sure why this should be counter intuitive Eugene : it's all a matter of context for the system you're in. After all, you wouldn't allow a husband to hold more then a single wife(would you ), but you might want a father to be able to have multiple children.
    In the airline industry, in which I have actually worked, there are usually business rules that disallow a Client Rep from booking more then a single flight at a time: it discourages business, for reasons I can go into if you're really interested. The point here is that you're not a business analyst in this exercise: you're a developer, and you should develop the simplest solution that will work. As of right now, there is no compelling reason to design locks/clints vs clients/locks, because we can't anticipate the business needs of the client.

    -- The entries of WeakHashMap are not released until the WeakHashMap is altered. If you do not call any mutator methods after populating the WeakHashMap, the values and WeakReference objects will never be dereferenced.

    completely untrue, as demonstrated in the following snippet, run on windows xp with jdk 1.4.1


    -- Since WeakHashMap wraps its internal HashMap, there may be some significant performance overhead.

    There are absolutely no significant performance overheads, since we're talking about millisecond here, and in some cases, hashmaps are actually faster then treemaps(can't seem to find the link, but I believe we discussed this before: Gosling even got involved in the discussion). It's important to be aware of context, as we're talking about 20 some flights here. At any rate, the directions are clear that performance is not a consideration that should hold no water against a simpler design. If the design options were equally simple, then this sort of secondary issue would be a tie breaker. Since we have not established that the designs are, in fact, equally simple, this is a non sequitur. As a matter of fact, if I can get you to hold on, I hope to demonstrate that the design that uses the weakHashmap is more simple.

    Every call to get() creates a new WeakReference object to enable equality testing of keys in the internal HashMap. The size() is an operation that takes time proportional to the size of the WeakHashMap, since it has to go through all the records to count those that have not been cleared. isEmpty() iterates through the collection to find a non-null key.

    Again, true, but irrelevant. How do you think that unrefernced works? There are complexities in how the unreferenced works that make the above seem like a walk in the part. For example, did you know that unreferenced can be called several times.

    Of course, both WeakHashMap and Unreferenced will do the job and you will pass.

    On this we agree. And I think that we also agree that, as far the criteria the graders use, speed and record to client vs. client to record locking is irrelevant. Thus, the only remaining issue is complexity and elegance.


    However, since Unreferenced is a standard solution to garbage collection in RMI, it seems more appropriate in the context of this assignment.

    Not at all. The unrefernced interface is a standard solution if you need to remote object to do something before it exits. However, in this assignment, you do not need such if you implement your architecture carefully, because by the very act of leaving, the remoteObject does the only relevant thing it should: that it, freeing it's lock.

    Using WeakHashMap instead of Unreferenced to clean the remote objects in RMI would be like coding your own merge sort instead of using the sort() method in the Collections interface.

    Actually, in a remote system, just as in a local system, it's best to automatically delete objects that don't have a reference. If you can get that for free by using a WeakHashmap, in addition to releasing the locks those objects hold, then using Unreferenced seems, to me, not to be the most elegant solution.
    I would choose unreferenced if I had anything complicated to do, but in this case, that's not context in which we find ourselves. It's a bit like paying $50 for a mechanic who will tightens a screw on your motorcycle. If you know what he's doing, and you know enough to tighten the screw, then it seems silly to involve him. Or her.

    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4
    Max Habibi
    town drunk
    ( and author)
    Sheriff

    Joined: Jun 27, 2002
    Posts: 4118
    Originally posted by HS Thomas:
    Would
    ensure that client locks will always dereference safely, whereas WeakHashMaps may never dereference under conditions quoted in :
    regards

    The example below clear debunks the assertion you're basing this statement on. Of course, you may have to increase the size of the loop variable when you test this code on your own system, since the gc is whimsical
    Max Habibi
    town drunk
    ( and author)
    Sheriff

    Joined: Jun 27, 2002
    Posts: 4118
    Not so fast, pardner .
    Originally posted by HS Thomas:
    [QB]Sorry, couldn't resist the following :
    The weightings are my own. QB]

    A couple of thoughts.
    *"A client connection can lock multiple record". I'm not sure why this gets a rating of 2, since it's not a requirement, and may actually be counter intuitive to the business needs. It would be equally arbitrary to design that "A client connectin can lock only a single record" deserves a 2. The fact of the matter is, we don't know.
    "Best for unreferencing remote objects using RMI" and "Best for unreferencing remote objects without RMI" are a little confusing, I think. RMI provides for the release of unreference remote objects, regardless of whether those object implement Unreferenced or not. What you're really doing by choosing Unreferenced is choosing to write your own code, that may require synchronization and whatnot, to support the release of locks safely. IMO, it's always better to get this sort of thing for free.
    Here's the thing: which Unreferenced, you're asking the RemoteObject to do things before it dies, the same way you might use a finally. However, if you use a weakHashMap to hold the client, then you don't need any of that: You just need for the client to die, and the lock will be released automatically.
    "Will always be dereferenced", as per the code example I provided, is equally true for both approaches.
    "The Distributed Garbage Collector is involved " and "The Server-Side Garbage Collector is involved", likewise, is also true for both approaches.
    Also, consider the very important facts that the WeakHashmap approach decreases complexity of the code(no Unreferenced, thus less complexity), reduces the amount of code you have to write(the actual method on the RemoteObject), and decreases the amount of code that has to be maintained. A simpler, more maintainable design that is more easily understood by a junior programmer.
    I'd like to see this reflected in the chart, if you still willing to update it.
    All best,
    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404
    Hi Max,
    *"A client connection can lock multiple record". I'm not sure why this gets a rating of 2, since it's not a requirement, and may actually be counter intuitive to the business needs. It would be equally arbitrary to design that "A client connectin can lock only a single record" deserves a 2.

    I think we are all agreed that implementing a way of clearing dead client locks is outside the scope of the assignment.In practise handling of multiple record locks simultaneously can be a business mission critical requirement. (This was originally a 4, but downgraded to a 2 as I thought only a small percentage of businesses would require it. )

    "A client connectin can lock only a single record" deserves a 2.

    I think you are absolutely correct there and will add this to the chart.

    I'd like to see this reflected in the chart, if you still willing to update it.

    Why not ? I've accepted everything else on face-value.
    I am thinking of adding a weighting of 1 point for any Testable assertion that can be provided to support any of this. And a further 1 point if it passes. Give me a moment.
    :roll:
    regards
    [ March 20, 2003: Message edited by: HS Thomas ]
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404

    I have summarised the following :


    into a single equivalent nice-to-have , ie
    | 3 | Allows for unreferencing of remote objects safely | X | X
    and added +1+1 for the Test Case and passing the test.(I've still got to do the test. I'll remove the point if it doesn't pass)
    Everyone, Happy?
    Any ideas on how to capture ease of implementation, junior programmer friendly ?
    regards
    [ March 20, 2003: Message edited by: HS Thomas ]
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404

    Hope I have been fair.
    Start giving me some tests /benchmarks to swing it one way or another, please.
    If I were to put an Assignment context on it, I'd have a 0 weighting on client can lock multiple records and on No performance overhead.

    regards

    [ March 20, 2003: Message edited by: HS Thomas ]
    Max Habibi
    town drunk
    ( and author)
    Sheriff

    Joined: Jun 27, 2002
    Posts: 4118
    HS,
    One little bone to pick regarding the maintainability. I was making the point that a developer needs to understand less complexity, and to write less code, in using the WeakHashMap solution then in the Unreferenced solution. That is, to use the unreferenced structure, you need to
    1. write a thread safe unreferenced method
    2. implement the unreferenced interface,
    and dig into the spec to see that it works safely.
    3. Make one more call to the RemoteObject

    In the WeakHashMap structure, you need:
    None of the above.

    If you agree with this assertion, then it would seem clear that the complicity of the WeakHashMap solution is less. Thus, by common design paradigms, and by the standards of the scjd assignment, this is the the preferable solution.
    Finally, to my point. The WeakHashMap implementation deserves more points, because it is less complex, and that's a stated goal of this assignment. I could actually see a grader deducting points because you've gone to a great deal of trouble to implement a solution that wasn't required, thus increasing complexity for no justifiable reason. The WeakHashMap goes to no trouble whatsoever, and provides exactly the same solution. Thus, to me, it seems like a better solution.
    All best,
    M, author
    The Sun Certified Java Developer Exam with J2SE 1.4
    [ March 20, 2003: Message edited by: Max Habibi ]
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Originally posted by Max Habibi:
    Not sure why this should be counter intuitive Eugene : it's all a matter of context for the system you're in.
    True. And looking at the properties and constraints of the problem (funcionality, mathematical, performance, whatever slant you take on it), a WeakHashMap forces you to map exactly the wrong way around. It makes the code much less expressive of the problem, and introduces performance penalties arbitrary constraints in the process, without justification (in my eyes) in simplicity, functionality, or performance. I've already beaten this subject to death; I won't repeat that here.
    In the airline industry, in which I have actually worked, there are usually business rules that disallow a Client Rep from booking more then a single flight at a time
    I believe it is an absolute mistake to look at the database as a flights database. The Data class you've been given makes this clear in no uncertain terms. Whoever wrote it went the extra (air) mile or two to make it absolutely, completely generic with zero, zip, zilch FBN dependence or FBN-specific assumptions. This is the class we are being asked to modify and enhance.
    There are absolutely no significant performance overheads, since we're talking about millisecond here, and in some cases, hashmaps are actually faster then treemaps
    They obviously are faster, as hashing gives you O(1) performance on most things where trees give you O(log N) performance. But we aren't comparing HashMaps to TreeMaps. We're comparing HashMaps to WeakHashMaps; AFAIK both have the same big-O behaviour. WeakHashMaps are slower but, as you note, it does not really matter much -- we've not been asked to develop for performance -- it's just another very small and minor exhibit in the case against a WeakHashMap.
    How do you think that unrefernced works? There are complexities in how the unreferenced works that make the above seem like a walk in the part. For example, did you know that unreferenced can be called several times.
    You're suggesting complexity where there isn't any. Unreferenced will be called multiple times only when, after losing all remote references, you start handing out new references to remote client. That simply makes sense, and is not at all relevant in the FBN case.
    Unreferenced is a pretty straightforward, standard part of the RMI API which was conceived precisely to do what we want to achieve here, that is, be notified of the loss of the client's reference. As you say, "The unrefernced interface is a standard solution if you need to remote object to do something before it exits." -- well, that's exactly what we want to do: we want the remote object to clean up its locks. I think you generally will have to come up with very compelling reasons indeed to ignore standard API in favour of your own thing. Note that the requirements explicitly state that you should use standard API wherever possible.
    You do of course say that WeakHashMap is also standard API. Which it is, but not for this task.
    Actually, in a remote system, just as in a local system, it's best to automatically delete objects that don't have a reference. If you can get that for free by using a WeakHashmap, in addition to releasing the locks those objects hold, then using Unreferenced seems, to me, not to be the most elegant solution.
    If you can get it for free, yes... but not at the expense of expressivity of the problem domain, arbitrary restrictions on server functionality, use of non-standard API, conceptual complexity, cleanup predictability (gc involved), lock availability after cleanup (no notifyAll!), and performance.
    That is, to use the unreferenced structure, you need to
    1. write a thread safe unreferenced method
    2. implement the unreferenced interface,
    and dig into the spec to see that it works safely.
    3. Make one more call to the RemoteObject
    In the WeakHashMap structure, you need:
    None of the above.
    But all of the below instead:
    1. Rejig your design to employ a counterintuitive mapping of clients to locks rather than, as the problem dictates, the other way around; ensure that your code enforces the one-owner-only nature of the locks that the data structure now no longer enforces.
    2. Document in your design decisions why the resultant restrictions in the lock() API were a good tradeoff. Please note that the Data javadoc implies no restrictions whatsoever on the number of records locked.
    3. Dig in the spec and API to understand how WeakHashMap works and how it affects your design. The difference between soft, weak and phantom references, anyone? Don't forget to go through the RMI specification to ensure that you are guaranteed that RMI releases all references to your object. After all, you cannot rely on the behaviour of the particular RMI implementation you happen to be using.
    4. Carefully go over your code to ensure that the fact that WeakHashMap doesn't obey the usual Map invariants doesn't affect your code. For example, a call to map.containsKey(client) can return true yet a subsequent call to map.get(client) return null, even inside a synchronized block. This kind of odd behaviour may not affect you, but are you sure without fully understanding how WeakHashMap works and carefully inspecting your code? WeakHashMap is most emphatically not a simple, devoid-of-complexity drop-in replacement for HashMap as suggested.
    5. Find a way make sure that locks are actually cleaned up timely and notifyAll() gets called so a freed lock can actually find a new owner within a predictable, bounded time. I haven't seen any answer to this yet.
    - Peter
    [ March 20, 2003: Message edited by: Peter den Haan ]
    Peter den Haan
    author
    Ranch Hand

    Joined: Apr 20, 2000
    Posts: 3252
    Max Habibi wrote:Finally, to my point. The WeakHashMap implementation deserves more points, because it is less complex
    Unsurprisingly, I don't agree at all with this assessment. From where I sit, it looks more complex: it is more invasive, makes your code harder to read, is conceptually more difficult, non-standard, and less predictable.
    It might be good to refresh our minds what complexity we are actually talking about:Actually, the deceptively simple exterior doesn't do justice to all the subtle issues we discussed. But it is significant that the code impact of using a WeakHashMap is much larger[1], functionality impact likewise, and the issues no less subtle.
    - Peter
    [1] Assuming that you'd otherwise have chosen the mapping that most naturally fits the problem.
    [ March 20, 2003: Message edited by: Peter den Haan ]
    HS Thomas
    Ranch Hand

    Joined: May 15, 2002
    Posts: 3404
    Max,
    I accept implementing WeakHashMap is less complex.
    But a programmer doesn't have to be a rocket scientist to implement Unreferenced.
    Hence the 1 point weighting.



    Any tests to prove/disprove any of the above assertions.
    regards
    [ March 20, 2003: Message edited by: HS Thomas ]
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Using Unreferenced vs a daemon thread