File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes lock/unlock review 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 "lock/unlock review" Watch "lock/unlock review" New topic
Author

lock/unlock review

Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
This is my lock and unlock, Please comment.
In Data i have a LockManager class.
Lock and unlock is done this way in Data:


The LockManager lokks like this(locks is an ArrayList):

Any comments would be great!
Thanks.


Free software is a matter of liberty, not price.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Raffe,
My first comment is that your unlock doesn't seem to check the credentials of the locking client, per the instructions, so that's probably not good.
But I have another concern. There are already simply, preexisting structures out there(Hashmaps, treemaps, etc.,) that could serve the same function as your LockManager. Instead of creating your own static data structure, why not simply using a static Map? Doesn't the scjd explicitly warn against this sort of thing? That is, writing your own class where a pre existing java.api class will do? I'm just wondering what your criteria were for working through this issue.
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
[ March 29, 2003: Message edited by: Max Habibi ]

Java Regular Expressions
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

There are already simply, preexisting structures out there(Hashmaps, treemaps, etc.,) that could serve the same function as your LockManager.

Max, could you clarify your point, please? I had an impression that many of us shared an opinion that a separate class such as LockManager that contains a collection of locks is a sound solution. Do you disagree with that?

Instead of creating your own static data structure, why not simply using a static Map?

Doesn't the static map limit you to only one database?
Eugene.
[ March 29, 2003: Message edited by: Eugene Kononov ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Hi Eugene,

Max, could you clarify your point, please?

It's more of a question then a point.

I had an impression that many of us shared an opinion that a separate class such as LockManager that contains a collection of locks is a sound solution. Do you disagree with that?

Some do, others don't. As you know, I get a great deal of mail on the scjd directly, and the concept of a lockmanager is confusing to a lot of people. Since it's not a design choice I generally advocate, I'm interesting in the reasoning process of someone who's currently taking the exam, and who's decided to use it.
I don't disagree that a lock manager works, but I'm a big advocate (as you know) to coding exactly to specifications, and the LockManager seems to exceed them: that is, there is no second database, and no indication that there will be.
I generally suggest coding to the minimal requirements. I'm interested in Raffe's reasoning. If his reason for using a lock manager is he's expecting future enhancements to the database, that's well and good. However, if so, then he should probably also be extending Data instead of modifying, etc., for the sake of design consistency.


Instead of creating your own static data structure, why not simply using a static Map?

Doesn't the static map limit you to only one database?
Eugene.

Not really, because other maps can be added( or a lockManager can put into place), if it ever is required.
All best,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Max,
My first comment is that your unlock doesn't seem to check the credentials of the locking client, per the instructions, so that's probably not good.

Hmm, I dont understand this. What do you mean? What credentials?
Instead of creating your own static data structure, why not simply using a static Map?

Do you mean that I should put the implementation in Data and make lock/unlock synchronized in Data? But what should I put in the Map? I have only one Data object in my system so i cant track clients.
Thanks alla for looking at my stuff.
Raffe
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Raffe Paffe:Max,

---My first comment is that your unlock doesn't seem to check the credentials of the locking client, per the instructions, so that's probably not good.
Hmm, I don't understand this. What do you mean? What credentials?

If I'm not mistaken, your unlock method requires that only the client that originally locked the record be allowed to unlock it. To enforce this, you are required to track the locking GUI client. One way to do so is to give each remote GUI client their own unique RemoteData object. The Data object would have a static member variable which is a map( or a WeakHashmap, if you want to get fancy), and lock thusly



That way, your unlock method can make sure that the Data object currently locking record number, say, 13, is the same Data object that originally locked record 13.
Either way, using a Lock manager or a static map, I think the requirement say pretty strongly that you need to do this.
Make sense?

---Instead of creating your own static data structure, why not simply using a static Map?
Do you mean that I should put the implementation in Data and make lock/unlock synchronized in Data?

Yes, I think you should put the implementation in Data. After all, are the requirements that you must implement the lock/unlock method? That seems to imply that lock/unlock must be implemented .
Also, remember that you actually need to synchronize on the static Map, not the method lock.

But what should I put in the Map? I have only one Data object in my system so i cant track clients.

As I said above, I would put the Data instance and the recno in Data.

Thanks alla for looking at my stuff.
Raffe

Happy to help,
ALl best,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Max,
First, thanks for posting. I have changed my lock/unlock for a week now and I am a litle frustrated. I am NOT
getting something here. :-(
This is my design.
I have a RemoteDataImpl object and LocalDataImpl that implements DataInterface(with all the methods in Data).
My client gets a new RemoteDataImpl for each client. The RemoteDataImpl has a Data object. Theire is only one Data so they all
have the same.
In Data i have lock(int recno) and unlock(int rec).
So, I can use RemoteDataImpl to track the client since every client got its unique RemoteDataImpl, but how can i get it into
Data if i only have lock(int recno) and unlock(int rec)? This part i dont understand.
I use to have a lockmanager in RemoteDataImpl that had lock(this,recno) and that worked but as said in the instructions;
you must implement the lock/unlock in Data. So i moved it.So again how do i get the RemoteDataImpl into Data?
<Edit>
Reading your comment again, i wonder of the differnece between Data and RemoteData in your comment? Is it as my design RemoteDataImpl and Data or is it the same class??
</edit>
<edit>
If I'm not mistaken, your unlock method requires that only the client that originally locked the record be allowed to unlock it.

Where does it says this?I cant find it anyware!?
</edit>
Is my thinking and design correct?
Thanks a lot.
[ March 31, 2003: Message edited by: Raffe Paffe ]
[ March 31, 2003: Message edited by: Raffe Paffe ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Instead of creating your own static data structure, why not simply using a static Map?
A cornerstone of OO design is that a coherent and well-conceived class should do one thing, and do it well. It is easy to argue that the locking code is sufficiently complex and orthogonal to the other concerns of the Data/RemoteData/Connection class that a separate class is justified. This can also make sychronization cleaner. These arguments are quite independent of whether that class will be reused or not, or whether there will be more than one database.
Making any of the locking data structures static is unambiguously a mistake; it'd be an example of inappropriate use of singleton structures, wilfully building restrictions into the code without any simplification to justify it.
[...] lock thusly
Or, in the opinion of some much better, thuslyThis is more expressive of the fundamental properties of the record locks that you can only have one such lock outstanding per record.
Yes, I think you should put the implementation in Data.
It bears mentioning that many have argued that the empty implementations in the Data class itself are fine as they are (I'll leave the reasons why as an exercise for the reader), and implemented full lock() and unlock() functionality only in another class, the networked version of Data. Many passed with outstanding scores.
- Peter
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
I agree with both Peter and Max. :-)
My first design and implementation was with a lockmanager in RemoteDataImpl and no implementaion in Data. BUT, after reading some of Max's posts i do agree with him that i was not following the spec. So, even if its not the best solution i want to do it by the spec.
Now, could you please comment on my prevoius post?
Thank you all again.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Peter den Haan:
Making any of the locking data structures static is unambiguously a mistake;

Unsurprisingly, I don't agree at all with this assessment. From where I sit, it looks more complex: it seems redundant, and counter to one of the cornerstones of the scjd assignment, which is, "don't reinvent the wheel."

It bears mentioning that many have argued that the empty implementations in the Data class itself are fine as they are (I'll leave the reasons why as an exercise for the reader), and implemented full lock() and unlock() functionality only in another class, the networked version of Data. Many passed with outstanding scores.

Peter, I know that you took a much earlier version of the exam, so the requirements may have been different. However, in the current exam, there are must sections, which state that
the direction therein must be explicitly carried out, or the student will automatically fail. As such, I usually advise people who are preparing for the SCJD to believe Sun. The fact that some people have gotten away with it in the past nonwithstanding,
You seem to have very strong views on this issue, some of which, if I understand them correctly, I disagree. In the interest of keeping the tone of the current thread moderate, please help me by arguing your prespective on another thread.
Thanks,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

Max Habibi wrote:
However, in the current exam, there are must sections, which state that the direction therein must be explicitly carried out, or the student will automatically fail.

I'd like to point out that OO design is also a must, as explicitely stated in the requirements. Evaluated on the principles of class encapsulation, cohesion, and decoupling, a completely separate and independent LockManager is clearly superior than "a hashmap as a member of Data.java".
I got full score for my server design with LockManager and empty lock/unlock in Data, and this is as far from an "automatic fail" as it could be. If you choose to implement locking in local mode, fine. But it doesn't negate the value of LockManager where the locking logic is encapsulated.
Software engineering can be considered a form of art, but it is also a science with well establshed principles. One of these proven principles is that the software written to satisfy the current requirements with no regard to future requirements will invariably fail, because it will cost less to start a new project from scratch rather than change the unchangable. The entire history of evolution of computer languages is a study in code reuse and maintainance by abstracting the code to ever higher levels, from simple PROC in Assembler to higher level procedural languages, to OO languages, and ultimately to neuro-genetic constructs that evolve the source code without programmer participation.
Eugene.
[ March 31, 2003: Message edited by: Eugene Kononov ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Max Habibi:
Peter, I know that you took a much earlier version of the exam, so the requirements may have been different. However, in the current exam, there are must sections, which state that
the direction therein must be explicitly carried out, or the student will automatically fail.
So were there in older versions of the exam. But don't get too hung up on the particular version I did -- I've been hanging around here for ages now, moderated the forum for a fair while, and am reasonably familiar with a number of iterations of the exam.
You seem to have very strong views on this issue, some of which, if I understand them correctly, I disagree. In the interest of keeping the tone of the current thread moderate, please help me by arguing your prespective on another thread.
I believe I was quite moderate in tone; contemplating alternative perspectives doesn't hurt anyone -- especially not in this assignment. And as far as I'm aware, I have as much right to offer my perspective in this thread as you have to give yours.
- Peter
Max Habibi
town drunk
( and author)
Sheriff

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

I'd like to point out that OO design is also a must,

Originally posted by Eugene Kononov:
Of course it is, Eugene, I'm suprised that you feel this needs to be mentioned. Did I somewhere indicate that it wasn't? However, one man's 'code reuse' is another man's self-indulgant effort. And if you'd like argue where that line is, please start thread on it.
M
[ March 31, 2003: Message edited by: Max Habibi ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Peter den Haan:

So were there in older versions of the exam. But don't get too hung up on the particular version I did -- I've been hanging around here for ages now, moderated the forum for a fair while, and am reasonably familiar with a number of iterations of the exam.

Don't get too hung up on length of moderation time Peter. I've been helping people a while too, and I think I'm starting to see a dangerious tread here, where people are starting to feel that there's only one valid approach to the scjd. This is utter nonesense, of course, and not a moderate view at all.
I believe I was quite moderate in tone; contemplating alternative perspectives doesn't hurt anyone -- especially not in this assignment. And as far as I'm aware, I have as much right to offer my perspective in this thread as you have to give yours.
- Peter

Not only do you have a right Peter, you have an invitation from me personally: However, you don't have the right to hijack this thread, as I define hijacking a thread. Therefore, please start a new thread on general comparisons, if you're interested.
Thanks,
M
[ March 31, 2003: Message edited by: Max Habibi ]
[ March 31, 2003: Message edited by: Max Habibi ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Raffe Paffe:
Max,
First, thanks for posting. I have changed my lock/unlock for a week now and I am a litle frustrated. I am NOT
getting something here. :-(
This is my design.
I have a RemoteDataImpl object and LocalDataImpl that implements DataInterface(with all the methods in Data).
My client gets a new RemoteDataImpl for each client. The RemoteDataImpl has a Data object. Theire is only one Data so they all
have the same.

In Data i have lock(int recno) and unlock(int rec).
So, I can use RemoteDataImpl to track the client since every client got its unique RemoteDataImpl, but how can i get it into
Data if i only have lock(int recno) and unlock(int rec)? This part i dont understand.
I use to have a lockmanager in RemoteDataImpl that had lock(this,recno) and that worked but as said in the instructions;
you must implement the lock/unlock in Data. So i moved it.So again how do i get the RemoteDataImpl into Data?

Ok, I think I see where you're going here. First, I should say that there are some people who have done exactly what you've done, and they've done well on the exam. However, if you're the kind of person who takes specifications very seriously, then you might be uncomfortable with this approach.
My general feeling is that you should implement the lock/unlock in the Data class, or in a class that extends Data, and that you shouldn't change the signature. That being the case, consider the scenario where the Data class has a static Map of some sort. Well and good.
Now, since each GUI client has their own RemoteDataImpl object, and each RemoteDataImpl in turn has their own Data, then in effect, each GUI client has their own Data object.
this is why, if the Data object synchronized on that static Map, and the lock method in Data did something like


each GUI client would have a valid lock. Make sense?

Reading your comment again, i wonder of the difference between Data and RemoteData in your comment? Is it as my design RemoteDataImpl and Data or is it the same class??

Sorry, having a little trouble following this.


Where does it says this?I cant find it anyware!?

My assignment had

The unlock method simply removes the lock from the specified record. If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken.


Is my thinking and design correct?

Your thinking is fine: you're concerned about the appropriate things, and I think you'll work them out well. There are a lot of ways to skin this cat, and I don't think you'll have a problem.
All best,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Max Habibi:
Not only do you have a right Peter, you have an invitation from me personally: However, you don't have the right to hijack this thread, as I define hijacking a thread.
Sooo... given that every single point I addressed was relevant to the original question, how do you as a moderator of this forum define "hijacking a thread"? Expressing an opinion that doesn't agree with yours?
Or, perhaps, a thread gets hijacked when you start to turn contrasting views into a personal discussion such as the one we're engaged in right now instead of leaving it to Raffe to make up his own mind? You know, I specifically tried to formulate my response in such a way as to avoid exactly this -- by using phrases such as "in the opinion of some" -- it is you who can't leave well alone yet you accuse me of "hijacking" and acknowledging "only one valid approach". This is a complete perversion of the truth as I see it.
- Peter
[ April 01, 2003: Message edited by: Peter den Haan ]
Ta Ri Ki Sun
Ranch Hand

Joined: Mar 26, 2002
Posts: 442
Originally posted by Peter den Haan:
Sooo... given that every single point I addressed was relevant to the original question, how do you as a moderator of this forum define "hijacking a thread"? Expressing an opinion that doesn't agree with yours?
Or, perhaps, a thread gets hijacked when you start to turn contrasting views into a personal discussion such as the one we're engaged in right now instead of leaving it to Raffe to make up his own mind? You know, I specifically tried to formulate my response in such a way as to avoid exactly this -- by using phrases such as "in the opinion of some" -- yet it is you who can't leave well alone and accuse me of "hijacking" and acknowledging "only one valid approach". This is a complete perversion of the truth.
- Peter


please guys, i opened this thread expecting a discussion on lock/unlock, not a scene from some soap opera, move it to another thread as lots of this discussion has nothing to do with locking/unlocking, and is a waste of my time, effort and already limited bandwidth
Edit:
Disclaimer, i meant no disrespect to either of you(Peter/Max)
[ April 01, 2003: Message edited by: Taariq Levack ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Taariq Levack:
please guys, i opened this thread expecting a discussion on lock/unlock, not a scene from some soap opera, move it to another thread as lots of this discussion has nothing to do with locking/unlocking, and is a waste of my time, effort and already limited bandwidth
I couldn't agree more. I can't wait to junk all the excess baggage, and discuss stuff relevant to the locking design, such as tracking client identity (now that's at least something we all agree on), whether locking ought to be factored into a separate class, synchronization, modeling the lock/client relationship (which is N:1, set:collection on the problem domain level), modeling the local file/lock set/client relationship (1:1:N), and so forth.
Unfortunately, we seemed to have gone on a tangent that I'd rather have steered well clear of.
- Peter
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Raffe Paffe:
I have a RemoteDataImpl object and LocalDataImpl that implements DataInterface(with all the methods in Data).
My client gets a new RemoteDataImpl for each client. The RemoteDataImpl has a Data object. Theire is only one Data so they all
have the same.
Looks absolutely great so far.
In Data i have lock(int recno) and unlock(int rec).
So, I can use RemoteDataImpl to track the client since every client got its unique RemoteDataImpl, but how can i get it into
Data if i only have lock(int recno) and unlock(int rec)? This part i dont understand.
The problem you have here is an expression of the fact that you're trying to mix up the concerns for local, single-user database access with those for networked, multi-user access. Remember the one responsibility rule.
Upon reflection, my conclusion was and is that the implementations in Data as supplied are just fine the way they are (i.e. empty) and satisfy the requirements in every way (which in this regard haven't really changed over the years). After all, in the absence of any other competing clients they correctly implement the contract for lock() and unlock() as specified by the javadoc for these methods. This, I believe, is both the simplest possible implementation of the requirements and the most natural solution for the problem.
If this doesn't convince you and you are of the opinion that the instructions require you to put all of your locking code in Data itself, you have two problems on your hands. The first is: how do you get useful locking semantics when dealing with Data alone, i.e. in local mode? The second is the one you mentioned: how do I communicate my client ID?
You can kill both birds with one stone[1] by changing the signature of the lock() and unlock() functions. I think we all agree this would be a mistake.
You could solve the second problem by making RemoteData a Data subclass and implement your locking there. By making the lock map static, all Data subclasses still share the same locks. This design would be deeply wrong for a number of reasons. RemoteData would need to override virtually all methods without delegating them to its Data base class; this is not merely a code smell, it is an overwhelming code stench if there ever was one. In this design at least, RemoteData IS-NOT-A Data and should not have an inheritance relationship. The static lock map introduces an inappropriate Singleton; one sign of this is that you suddenly get funny restrictions, such as only ever being able to use one database file per JVM -- your colleagues coding the rest of the system, or enhancing it in the future, will be very pleased when they find this out (do, however, not identify this consequence as the reason why the singleton is inappropriate; it is just one consequence of a fundamental design flaw). On top of all this, it doesn't address the first problem in any way.
Another approach for the second problem could be to add new package-private lock() and unlock() methods which take a client ID. They would sit a bit uncomfortably next to the client-visible lock() and unlock() (another code smell, but you might judge it to be a bearable one); it would work though. The locks could simply be an instance field of Data in that case.
On the other hand, implementing something doesn't mean the implementation cannot delegate to another class -- after all, you can implement locking yet delegate most of the hard work to a class like HashMap, so why wouldn't you be able to leave most of the sweating to a LockManager if the problem demanded a design like that? Both Data and RemoteData could delegate to a private LockManager instance. Data would not need any additional methods unrelated to its core function, or modifications in method signatures.
That still leaves the first problem: what does locking mean for Data itself? What are different clients in the context of a local database? The only reasonable suggestion I've ever seen in the many discussions is to use the current Thread as the client identifier. There are however three problems with this. First, the javadoc does not even hint at this; admittedly, they don't hint at pink elephants either but in contrast to pink elephants, you would expect such a concept of identity to be documented there. Second, this only works outside an RMI context; I understand everyone is now in agreement on this. Finally, it would mean radically different semantics for lock() and unlock() in local mode vs. remote mode. This, again, seems wrong. If two classes implement the same interface, they should really implement the same semantics for the methods in that interface; all else dilutes the significance of the interface and introduces the potential for subtle and not-so-subtle problems. If different threads would need to embody different clients, they should get different DataInterface implementations (a RemoteData or similar, but used locally).
In conclusion, it would seem that implementing locking inside Data itself quickly leads you into a quagmire of contradictions, complexity, arbitrary restrictions and plain old bad design. However there are no doubt alternatives that I have missed. Max? You seemed to have another alternative in mind, one where each client has its own copy of Data? Can you elaborate?
As a final word, I'd like to add that I don't believe for a moment that Sun intended their instructions to stand in the way of good design and industry best practice. If you find that this is the case, you are either doing something wrong in your design or interpreting the instructions in a way they were never meant to be.
Pick your poison
- Peter
[1] No actual birds were harmed in the writing of this reply.
[ April 01, 2003: Message edited by: Peter den Haan ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Peter, you were warned.
M
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Max, Peter
Thank you both for your answers and commants.
I will do the only right thing. I will sleep on it.
:-)
I will return with my comments tomorrow.
Thank you.
Raffe
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Peter, since you seem to be making a effort to focus your points to the issue @ hand, I'm going to let this thread continue for a bit.If it starts to lose focus again, I'm move it accordingly.
Originally posted by Peter den Haan:
The problem you have here is an expression of the fact that you're trying to mix up the concerns for local, single-user database access with those for networked, multi-user access. Remember the one responsibility rule.
Upon reflection, my conclusion was and is that the implementations in Data as supplied are just fine the way they are (i.e. empty) and satisfy the requirements in every way (which in this regard haven't really changed over the years). After all, in the absence of any other competing clients they correctly implement the contract for lock() and unlock() as specified by the javadoc for these methods.

Peter is correct that in local mode, no competing clients should be expected: maybe people have argued that is meant to be 'admin mode' and locking shouldn't even apply. However, I read to requirements as stating the lock and unlock be implemented in Data, so my feeling is that, regardless of where it is used, that is what Sun wants to see. It also seems, to me, that this is probably the easiest way for the assessor to grade your paper, so all things considered, I advocate this approach.

This, I believe, is both the simplest possible implementation of the requirements and the most natural solution for the problem.

Yes: however, IMO, this is not in strict adherence to the requirements, because they don't implement the requirements that lock actually lock records, and that unlock actually unlock records.. Certainly, you can argue that, in the absence of other clients, they don't need to do so: However, this is not the same argument as saying that they actully do implement something when they are, in fact, empty!

If this doesn't convince you and you are of the opinion that the instructions require you to put all of your locking code in Data itself, you have two problems on your hands. The first is: how do you get useful locking semantics when dealing with Data alone, i.e. in local mode? The second is the one you mentioned: how do I communicate my client ID?
You can kill both birds with one stone[1] by changing the signature of the lock() and unlock() functions. I think we all agree this would be a mistake.

We do: IMO, this would be a fundamental mistake, IMO. You would really be avoiding the challenge that Sun set out for you, in leu of another challenge that you found more interesting and easier.

You could solve the second problem by making RemoteData a Data subclass and implement your locking there. By making the lock map static, all Data subclasses still share the same locks. This design would be deeply wrong for a number of reasons. RemoteData would need to override virtually all methods without delegating them to its Data base class;


Peter, I'm a little confused on why you think this is true? Not that I advocate the approach of extending Data, but why do you think the extended class would have to re implement all of it's methods?

this is not merely a code smell, it is an overwhelming code stench if there ever was one. In this design at least, RemoteData IS-NOT-A Data and should not have an inheritance relationship. The static lock map introduces an inappropriate Singleton;

This is a correlative argument, not a causical one. Putting the HashMap next to an ibm link that suggest that sometimes, some singletons are bad is not a conclusive logical tactic. Also, how many instances of the LockManager are you suggesting?

one sign of this is that you suddenly get funny restrictions, such as only ever being able to use one database file per JVM -- your colleagues coding the rest of the system, or enhancing it in the future, will be very pleased when they find this out (do, however, not identify this consequence as the reason why the singleton is inappropriate; it is just one consequence of a fundamental design flaw). On top of all this, it doesn't address the first problem in any way.

Labeling the above as restrictions misses the point. Your fictional colleagues, managers, etc can certainly extend the system if they are required to do. However, since they are not required to do so right now, I suggest that you Do the simplest thing that works, and leave it at that.

Another approach for the second problem could be to add new package-private lock() and unlock() methods which take a client ID. They would sit a bit uncomfortably next to the client-visible lock() and unlock() (another code smell, but you might judge it to be a bearable one); it would work though. The locks could simply be an instance field of Data in that case.
On the other hand, implementing something doesn't mean the implementation cannot delegate to another class -- after all, you can implement locking yet delegate most of the hard work to a class like HashMap, so why wouldn't you be able to leave most of the sweating to a LockManager if the problem demanded a design like that? Both Data and RemoteData could delegate to a private LockManager instance. Data would not need any additional methods unrelated to its core function, or modifications in method signatures.

This finally brings us back on track to the question which started this thread. Why use a lockmanager? Reasons for doing so are the expectation of future functionality: that is, you anticipate that future requirements will drive you to need a lock manager. However, this violates the YAGNI rule, which states

If you don't need it now, don't add it now.


That still leaves the first problem: what does locking mean for Data itself? What are different clients in the context of a local database? The only reasonable suggestion I've ever seen in the many discussions is to use the current Thread as the client identifier. There are however three problems with this. First, the javadoc does not even hint at this; admittedly, they don't hint at pink elephants either but in contrast to pink elephants, you would expect such a concept of identity to be documented there. Second, this only works outside an RMI context; I understand everyone is now in agreement on this. Finally, it would mean radically different semantics for lock() and unlock() in local mode vs. remote mode. This, again, seems wrong. If two classes implement the same interface, they should really implement the same semantics for the methods in that interface; all else dilutes the significance of the interface and introduces the potential for subtle and not-so-subtle problems. If different threads would need to embody different clients, they should get different DataInterface implementations (a RemoteData or similar, but used locally).
In conclusion, it would seem that implementing locking inside Data itself quickly leads you into a quagmire of contradictions, complexity, arbitrary restrictions and plain old bad design.

Actually, this is not a conclusion Peter, it's a statement. While you have made other subjective statements like 'this code smells', 'plain old bas design' etc., those have not been supported in the context of this assignment: they have been partially supported in the context of tangental design interpretations, but that is not sufficient to force a conclusion,

However there are no doubt alternatives that I have missed. Max? You seemed to have another alternative in mind, one where each client has its own copy of Data? Can you elaborate?

Actually, my opinion on this matter is that somewhat similar to yours, except that is less complex, IMO. That is, by all means, use a single class, shared by all instances of RemoteData keep track of Locks: but use a static HashMap that is a member variable of Data, not a LockManager that resides outside of the class. This fufils all of the requirements of the exam nicely, and provides a straight forward implementation. IMO, There is no complelling impetuous using a LockManger, unless both of the following points are met.
1. You feel that the specifications require you to design for future db functionality in this direction
2. You know what the nature of the future functionality will be.
Since I feel that the first is true, and I find it useless to speculate on the second(maybe they'll just replace this toy db with a real db? Maybe they estimating the project & budget based on the explicit requirements they asked for?), I naturally don't fall into the category.

As a final word, I'd like to add that I don't believe for a moment that Sun intended their instructions to stand in the way of good design and industry best practice. If you find that this is the case, you are either doing something wrong in your design or interpreting the instructions in a way they were never meant to be.

I think that the people who wrote the exam were probably very bright, and had certain goals in mind. But obviously, there are different interpretations on what consistent good design and industry best practice. I seem to favor it towards limiting scope and coding rigiously to the specifications. You seem to favor more full bodied solutions. Can we agree that there is more than one valid way of addressing this problem?
M
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Max Habibi:
Peter, since you seem to be making a effort to focus your points to the issue @ hand, I'm going to let this thread continue for a bit.
You are too kind. Unfortunately, I have no recollection of doing anything other than trying to focus on the issue at hand. But let's allow this matter to rest.
Peter is correct that in local mode, no competing clients should be expected [...] However, I read to requirements as stating the lock and unlock be implemented in Data, so my feeling is that, regardless of where it is used, that is what Sun wants to see.
So you think Sun's intention is for you to put the code in the Data class, even though it serves no purpose there, and is related to another class altogether?
I guess this is the point where rational argument ends and we just have to let the respective opinions stand. It is beyond my belief that in an assignment which is to a significant extent about design, those bright people at Sun require you to compromise your design to such an extent.
It seems to me that reading the instructions as requiring that all the locking code reside in Data itself is reading many more constraints into them than are actually there.
However, this is not the same argument as saying that they actully do implement something when they are, in fact, empty!
Anything satisfying the javadoc contract is a valid implementation of the requirements -- if that's a no-op implementation, great. That's polymorphism for you. You get exactly the implementation you require.
Peter, I'm a little confused on why you think this is true? Not that I advocate the approach of extending Data, but why do you think the extended class would have to re implement all of it's methods?
They all have to delegate to a shared Data instance, eventually. Actually, this is not strictly true; there's been one participant in this group who got everything to work with multiple File objects and Data instances over the same disk file. Not pretty, not necessary, and not an approach I would advocate.
This is a correlative argument, not a causical one. Putting the HashMap next to an ibm link that suggest that sometimes, some singletons are bad is not a conclusive logical tactic.
I'm leaving the rest as an exercise for the reader. In particular, there is a three-point test in the article which helps you determine whether you are really looking at a Singleton. Anyone reading this can follow the link and do the test. The wiki link intelligently discusses various takes on the purpose behind Singletons, when to use them, and when not to use them. I don't think a full-blown discussion in this group would be productive at this point.
However, since [your colleagues] are not required to [build the rest of the system, or extend FBN] right now [...]
Aren't they? What we are building in the assignment is quite evidently only a fragment of a system. Another subsystem will have to read the flights table and... well... given the restrictions you built into it, they have to develop all their other database needs from scratch as they can't use your Data stuff.
But let's not get drawn into this discussion again. As I indicated, it is just one consequence of a fundamental design flaw. There are more important matters, such as the role of Singletons in software design.
Why use a lockmanager? Reasons for doing so are the expectation of future functionality
No it isn't, and I'm sure I stated as much earlier. Of course, all things being equal, the fact that a LockManager is much more amenable to re-use is a very good thing, but that's not the main point.
The main point is that it is a coherent set of concerns that are sufficiently different from and orthogonal to the other responsibilities in the (Remote)Data class to be refactored into another class. Not coincidentally, it turns an awkward bit of explicit synchronization using synchronized blocks into simple synchronized methods.
Actually, this is not a conclusion Peter, it's a statement.
Oh no, please, not again -- it's getting tired now. I did highlight in some detail a fair number of significant problems and questions which crop up when you try to stuff locking into Data. When I then conclude that there are problems associated with this choice (ok, so I used more colourful language), it is little more than a summary of what has come before; you cannot simply dismiss this as a "statement". It's high-handed assertions like yours here that make rational discussion derail time and time again. Please don't.
[...] That is, by all means, use a single class, shared by all instances of RemoteData keep track of Locks: but use a static HashMap that is a member variable of Data
Now there's scope for some focused discussion. If there's a single Data, what do you gain by making the lock manager static?
Myself, I don't see at all what you'd gain, and plenty that you'd lose: Any expression of the fact that the lock Set is tied directly (1:1) to a database file. The ability to ever use more than one such file. And unless you turn Data itself into a Singleton, you set yourself up for maintenance problems when an unwary developer tries to create more than one instance of it.
I seem to favor it towards limiting scope and coding rigiously to the specifications. You seem to favor more full bodied solutions. Can we agree that there is more than one valid way of addressing this problem?
I'm not sure that I favour "more full bodied solutions" -- but I do attach great importance to the relation between the object model and the problem domain, and observe that when you get that right you often end up with more flexible, easier to understand and maintain designs without increased complexity. I do also think that for many, the Developer's exam is one of the rare opportunities to pursue that goal to a greater extent than they would normally be able to do; and that, when you take the trouble to do this, you will come out as a much better designer and developer. On the other hand, there's no way I would promote features beyond the scope of the assignment for their own sake[1].
There is certainly more than one way to skin this particular cat[2], and on many occasions I've helped ranchers along paths that were quite different from my own. But there are also ways that the cat really shouldn't be skinned -- certainly not if that comes in the form of firm and authoritative advice from an author and moderator.
- Peter
[1] The sole exception was that, like you, I used to promote lock cleanup simply because it was so laughably easy to do; after all the discussions we had lately, I'm no longer convinced that this is such a good idea unless you really know what you're doing.
[2] No actual cats where harmed in the construction of this reply.
PS. I'm glad you enjoy the C2 Wiki
[ April 01, 2003: Message edited by: Peter den Haan ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118

You are too kind. Unfortunately, I have no recollection of <snip>

I've often been told that I am too kind: and that I am too short, and too bald.

quote:
--------------------------------------------------------------------------------
Peter is correct that in local mode, no competing clients should be expected [...] However, I read to requirements as stating the lock and unlock be implemented in Data, so my feeling is that, regardless of where it is used, that is what Sun wants to see.
--------------------------------------------------------------------------------

So you think Sun's intention is for you to put the code in the Data class,

Yes, since that is exactly what they ask you to do .

even though it serves no purpose there, and is related to another class altogether?

Peter, this is just your opinion, no matter how strongly you feel it. I feel that it does naturally belong there, and I feel that the requirements are explicit on this point when they say: "you may implement(lock/unlock) in two ways. by modifying the Data class or extending it"

I guess this is the point where rational argument ends

rational argument only ends when one or both of the parties choose to ignore it. The requirements are explicit and clear to me. "you may implement(lock/unlock) in two ways. by modifying the Data class or extending it". This may not be convincing argument to you, but it is rational. I'm surprised that you don't see this.


and we just have to let the respective opinions stand. It is beyond my belief that in an assignment which is to a significant extent about design, those bright people at Sun require you to compromise your design to such an extent.

Yes, if it had been objectivity agreed that such is a design compromise. However, that is a subjective opinion(yours), and thus not compelling. It like to see an objective argument that doesn't resort to pejoratives like 'natural', 'better', 'stench', etc. So far, I have not.

It seems to me that reading the instructions as requiring that all the locking code reside in Data itself is reading many more constraints into them than are actually there.

That is the point of specifications, to provide a guide that will serve as a literal interpretation.

quote:
--------------------------------------------------------------------------------
However, this is not the same argument as saying that they actually do implement something when they are, in fact, empty!
--------------------------------------------------------------------------------
Anything satisfying the javadoc contract is a valid implementation of the requirements -- if that's a no-op implementation, great. That's polymorphism for you. You get exactly the implementation you require.

The javadoc requirements, in addition to the explicit requirements that lock and unlock be implemented in Data or some extended class do not indicate this.

quote:
--------------------------------------------------------------------------------
Peter, I'm a little confused on why you think this is true? Not that I advocate the approach of extending Data, but why do you think the extended class would have to re implement all of it's methods?
--------------------------------------------------------------------------------
They all have to delegate to a shared Data instance, eventually. Actually, this is not strictly true; there's been one participant in this group who got everything to work with multiple File objects and Data instances over the same disk file. Not pretty, not necessary, and not an approach I would advocate.

This indicate that you're missing the point entirely. Each client has their own Data instance in the design I advocate.

quote:
--------------------------------------------------------------------------------
This is a correlative argument, not a causical one. Putting the HashMap next to an ibm link that suggest that sometimes, some singletons are bad is not a conclusive logical tactic.
--------------------------------------------------------------------------------
I'm leaving the rest as an exercise for the reader.

yes...

quote:
--------------------------------------------------------------------------------
However, since [your colleagues] are not required to [build the rest of the system, or extend FBN] right now [...]
--------------------------------------------------------------------------------
Aren't they? What we are building in the assignment is quite evidently only a fragment of a system.

I'm not sure what quite evidently means Peter: do you mean that there is some evidence to indicate this? If so, I'm not aware of it. However, that is beside the point here, and I think you are aware of this.

Another subsystem will have to read the flights table and... well... given the restrictions you built into it, they have to develop all their other database needs from scratch as they can't use your Data stuff.

Again, these fictional colleagues and fictional database don't exist in the world of the application, so it think it's folly to design for them. It's just as reasonable to assume that the system will serve business need sufficiently, or that the whole paradigm will be replaced in the future.

But let's not get drawn into this discussion again. As I indicated, it is just one consequence of a fundamental design flaw.

You did indicate this, but you have failed to substantiate that statement. But by all means, lets not get drawn into this again.

There are more important matters, such as the role of Singletons in software design.

Is this the issue that you 'left as a exercise'? Are you really indicating that a discussion you refuse to have(hopefully, on another thread) is the winning point of this argument?

quote:
The main point is that it is a coherent set of concerns that are sufficiently different from and orthogonal to the other responsibilities in the (Remote)Data class to be refactored into another class.

Ok, good. Now please defend this statement, without resorting to fictional future requirements, in light of the fact that the specifications explicitly state that lock and unlock need to be implemented in Data.

--------------------------------------------------------------------------------
Actually, this is not a conclusion Peter, it's a statement.
--------------------------------------------------------------------------------
Oh no, please, not again

The question has failed to be answered, and thus needs to be asked again.

-- it's getting tired now. I did highlight in some detail a fair number of significant problems and questions

But you did not.

which crop up when you try to stuff locking into Data. When I then conclude that there are problems associated with this choice (ok, so I used more colourful language), it is little more than a summary of what has come before; you cannot simply dismiss this as a "statement". It's high-handed assertions like yours here that make rational discussion derail time and time again. Please don't.

This is ridiculous on the face of it, and I expect better from you Peter. You have make unsubtaited statements, then used those to draw a 'conclusion' which 'proves' your point. Please, I know you can reason better then this.
quote:
--------------------------------------------------------------------------------
[...] That is, by all means, use a single class, shared by all instances of RemoteData keep track of Locks: but use a static HashMap that is a member variable of Data
--------------------------------------------------------------------------------
Now there's scope for some focused discussion. If there's a single Data,

Where did I say there was a single Data? Peter, have you been to Amsterdam lately ?

--------------------------------------------------------------------------------
I seem to favor it towards limiting scope and coding rigiously to the specifications. You seem to favor more full bodied solutions. Can we agree that there is more than one valid way of addressing this problem?
--------------------------------------------------------------------------------
I'm not sure that I favor "more full bodied solutions" -- but I do attach great importance to the relation between the object model and the problem domain,

You keep stating this: however, it does not appear to be supported by the facts on this discussion.

There is certainly more than one way to skin this particular cat[2], and on many occasions I've helped ranchers along paths that were quite different from my own. But there are also ways that the cat really shouldn't be skinned -- certainly not if that comes in the form of firm and authoritative advice from an author and moderator.

Well, I couldn't agree more

[1] The sole exception was that, like you, I used to promote lock cleanup simply because it was so laughably easy to do; after all the discussions we had lately, I'm no longer convinced that this is such a good idea unless you really know what you're doing.

Well, if you used a WeakHashMap, then you could avoid the needless complexity (ducking)
M
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

Now, since each GUI client has their own RemoteDataImpl object, and each RemoteDataImpl in turn has their own Data, then in effect, each GUI client has their own Data object.

Let me see if I understand it, Max. Since every client has its own instance of Data, the methods of Data are not synchronized anymore in between the different clients' invocations. To preserve the integrity of the database, the methods of Data must then be synchronizing on some other object, rather than the Data oject itself. And I understand that you suggest that the static collection of locks within Data should serve as that semaphore. So, as an example, the getRecord() method of Data which originally looked like this...

... would become

Something like that? That is, sprinkle the methods of Data with the critical sections? Is that the approach that you advocate?
Eugene.
[ April 01, 2003: Message edited by: Eugene Kononov ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Max Habibi:
you may implement(lock/unlock) in two ways. by modifying the Data class or extending it"
If this -- right next to each other -- is what it says these days[1], then it is unambiguous that Data must have some sort of non-empty locking implementation. Not that this would preclude delegation.
Other than that, I think the responses above can stand on their own; with the brutal moderation techniques employed in this forum (deletion of dissent without notification) I'm not in a mood to continue the discussion anyway.
- Peter
[1] In the past, both sentences were there but not quite in the same juxtaposition, and therefore not quite the same meaning.
Max Habibi
town drunk
( and author)
Sheriff

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

... would become

Something like that? That is, sprinkle the methods of Data with the critical sections? Is that the approach that you advocate?
Eugene.
[ April 01, 2003: Message edited by: Eugene Kononov ]


Not exactly Eugene: It is the responsibility of the client to lock, modify, and then unlock, just as most most databases do(you can have transactions support or you can not have it).
M
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

Max wrote:
Not exactly Eugene: It is the responsibility of the client to lock, modify, and then unlock, just as most most databases do(you can have transactions support or you can not have it).

My point is that if each client has its own instance of Data, the synchronized keyword in the methods of Data has no effect for intra-client communications. So, my question is, what mechanism in your design guarantees the integrity of Data (i.e, what prevents the file pointer moving all over the place in the db.db?)
Eugene.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Hi Eugene,
Sorry it took so long to reply: it's been a hectic day. As a matter of fact, nothing keeps the file pointer from jumping all over the place: there's no need to, in that you could literally have hundreds of file pointers, from different Data objects, pointing to the same file. So long as they don't try to modify the same bit of Data @ the same time( which is prevented by the locking mechanism), that's perfectly ok.
Of course, I don't expect you to take this @ my word , so I've written a sample app that spawns 100s of threads, and tries to modify the records concurrently. Then I went overboard and made it generic enough that anyone could use it to test their threading code: and now, I'm concerned that posting it would reveal too much, insofar that testing the app is really part of the code a developer should write on their own). However, I'm happy to send it to you personally( since you've already passed), along with the suggested implementation of lock/unlock if you like. Would that be convincing?
M
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937

However, I'm happy to send it to you personally( since you've already passed), along with the suggested implementation of lock/unlock if you like. Would that be convincing?

Sure, I would love to see it.
Eugene.
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Hi all.
I have read this thread many times the last days and its very interesting.
I have a lot of questions but i will post only a few.
Here we go:
Max wrote;

Actually, my opinion on this matter is that somewhat similar to yours, except that is less complex, IMO.
That is, by all means, use a single class, shared by all instances of RemoteData keep track of Locks:
but use a static HashMap that is a member variable of Data, not a LockManager that resides outside of the class.
This fufils all of the requirements of the exam nicely, and provides a straight forward implementation.

If I understand this comment correct you are saying that every client has a RemoteData and all
RemoteData have(share?) the same Data object. Implement a HashMap in Data and keep your
client id and lock number in that HashMap.
This is what I want. Now, could you please tell me how? I just dont get it! Or give me a hint?
If it is in the discusion eralier, I can not understand it. :-(
How do i pass the client id to Data? Can this be done? Reading Peters commants, this can not be done!
(well, easy or nice anyway)
If this can not be done do you suggest that i have a Data for each RemoteData?
Thanks again!
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Raffe Paffe:
If I understand this comment correct you are saying that every client has a RemoteData and all
RemoteData have(share?) the same Data object. Implement a HashMap in Data and keep your
client id and lock number in that HashMap.

Not exactly Raffe: every client has a RemoteData, and all RemoteData have their own Data object. However, all of those Data Objects share a static Map, which keeps track of the locks. Thus
Client_1 -> RemoteData -> Data
.......................................\
.........................................StaticMap
......................................./
Client_2 -> RemoteData -> Data
This way, when a Client_1's Data object does staticMap.put(this,recno), the Client_2
s Data is aware of it. make sense?
Again, I want to emphasize that I think that Peter's solution is a good one: it's just best (for you) to consider both options, understand them well, and decide which you want.
M
[ April 05, 2003: Message edited by: Max Habibi ]
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Thanks Max,
first:
Again, I want to emphasize that I think that Peter's solution is a good one: it's just best (for you) to consider both options, understand them well, and decide which you want.

My initial design and implementaion was verry much like Peters design but as i said i want to do it by the spec and nothing else. I know that we all read the spec differntlly but i understand it as you do in this case.
As i understand your design each Data object "points" to the same copy of the physical file and there is no probelm when one object "writes" when another "reads" (aka Eugene question as i understand it)? If i only write half the record and someone starts to read it, will that really work? Dont i have to syncronize on something or is it only in lock/unlock that i have to syncronize on the map?
I will now try to implement the "a data for a remotedata" and will post it here in a day or two.
Thanks again.
Looking foward to your comments.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
No, I don't think that dirty reads are a problem.
M
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Ok, here is the "Maxified" lock/unlock!

I have my code on another computer so the code might have som typos.
Ok, comments please! :-)
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11476
    
  94

Hi Raffe,
In the case where a lock cannot be granted instantaneously, you loop instantly trying to get it again. This will chew up a lot of CPU cycles.
If you are running on a virtual machine that does not implement pre-emptive multitasking, then your locking method could block the other threads from completing.
I think you should put back your calls to wait() and notify() so that other threads (and other applications) can get some of the CPU.
There were a few issues that I believe were just because of your transcribing the code - the compiler will warn you if you have them in your real code so I have ignored them.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
Max,
Is what Raffe Paffe posted really your code, from the book or some other source? Is that what you recommend?
Eugene.
Raffe Paffe
Ranch Hand

Joined: Feb 24, 2003
Posts: 92
Andrew :

If you are running on a virtual machine that does not implement pre-emptive multitasking,
then your locking method could block the other threads from completing.
I think you should put back your calls to wait() and notify() so that other threads
(and other applications) can get some of the CPU.

Good points!
This is my implemenation now(nevermind the else with system.out its just for debugging):
Please comment!


Eugene :
Is what Raffe Paffe posted really your code, from the book or some other source?
Is that what you recommend?

I understand that you dont like my code.Could you please comment why? I know you like
the lockmanager solution better but is there any error on my code?And hey,
dont try to blame Max, he does his best to learn me the way of the force.
:-)

Thanks again for your comments. Looking foward to more of them.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Hi Raffe,
A couple of quick thoughts: you probably don't want to use an if statement in your unlock when dealing with locks. See about using a while: here's why.
When a Thread slices out in the middle of an if-statement, it comes right back in to that same spot later when in slices back in. Paradoxically, that's not what you want. Why? Because the condition that caused you to check the if-statement might have changed, but your thread would never know.
This is where a while statement can help you. When a thread slices back into a while statement, the first thing it does is check the condition that started the while. Thus, your condition is checked again when the thread reenters, so that is what you want.
Also, since this is the first iteration of development, I would probably just ignore the DB_LOCK issue all together for right now. Once you have the rest sorted out, that part will fit in easily.
HTH,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
M
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Eugene Kononov:
Max,
Is what Raffe Paffe posted really your code, from the book or some other source? Is that what you recommend?
Eugene.

I think he's on the right track in terms of understanding my suggestion, but no, that's not my code, from the book or elsewhere.
M
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: lock/unlock review