aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Locking issues in Max's book sample project - Denny's DVD store 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 "Locking issues in Max Watch "Locking issues in Max New topic
Author

Locking issues in Max's book sample project - Denny's DVD store

Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hello ranchers,
I got a couple of doubts regarding the locking issues in Max's sample project. I know there is seperate thread for locking problems, but as this is related to sample project, am posting it seperately.
I will try to copy some related code here so that it will be easy for all to look into. The post will be a bit long, please be patient to have a look at it. Thanks.
Related code from DVDDbAdapter class.

Related code from DVDDatabase class.

Each and every client has their own DVDDbAdapter object which implies that they also have one DVDDatabase object. What I do not understand is the requirement of sychronization of methods in the DVDDatabase class.
Lets Consider there are five threads running t1, t2, t3, t4, t5. Three of the threads want to perform operation on upc=8 and two of the threads want to perform operation on upc= 3. Lets assume the following:
t1 wants to rent DVD with upc = 8
t2 wants to rent DVD with upc = 8
t3 wants to modify DVD with upc = 8
t4 wants to rent DVD with upc = 3
t5 wants to modify DVD with upc = 3
Now as each thread tries to perform the operation. In the DVDDbAdapter class, we are accessing the DVDDatabase object. Before the rent and modify operations we call reserve and release methods. In the release methods we are synchronizing on the reservedDVDs object and adding the upc to it.
I will describe the above operations as I understood.
Lets assume the flow is as follows:
t1 calls the reserve method and adds upc=8 to reservedDVDs. Then it tries to perform the rentoperation.
t2 also calls the reserve method with upc=8, but as it is already present in reservedDVDs, it waits giving up the CPU cycles.
t3 also follows in steps of t2(as it needs to work on upc=8)and ultimately gives up CPU cycles.
t4 calls the reserve method and adds the upc=3 to reservedDVDs. Now if t4 tries to rent, it cannot. Because as the rent method is synchronized, it has to wait till t1 completes its rent operation.
t5 calls the reserve method and gives up CPU as upc=3 is already present.
What I do not understand is, though t4 enters and gets lock of reservedDVDs, it cannot perform any operation as all methods are synchronized. It has to wait to perform for t1 to complete its rent operation and then only it can perform. But if we do not synchronize the rent method, then both t1 and t4 can perform simulataneous reads of two completely different dvds right? I do not see any problem in not synchronizing the rent method and modify method. Still the t2, t3 are waiting in reserveDVD method to get lock. t4 can do its work simulatneouly as t1. I'm not sure if its right. So, please correct me if I'm wrong? Thanks.
I do not understand the purpose of synchronizing the rent method. Those other threads which want to perform read operation on any other DVD also, MUST wait till the current thread is completed. So as far as I understood the read operation CANNOT be performed simultaneously on different DVD's also. Is my interpretation right?
And secondly there were many big threads which discussed about the purpose of notifyAll() in the reserveDVD() method. I think, the presence of notifyAll is also critical in the reserveDVD method. Because in the above scenario, threads t2...t4 are still waiting to get a lock on reservedDVDs object. So if we don't notify, how are they going to get notified?
Oh yeah! Its really big thread, I know. Thanks for going through.
Appreciate your help.
[ February 19, 2004: Message edited by: Satish Avadhanam ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Boy, I'm really tempted to ignore any post that starts with "Max's book sucks!', but I'm game
By and large, you need to remember Denny's DVDs was designed to be a teaching tool: it's designed to illicit exactly these sorts of questions. Do you really want to know what happens if the synchronization is removed? Trying removing it

Nothing happened? Maybe you're right, and the some of the synchronization in Denny's is frivolously(does this imply that the corresponding calls in certain versions of the SCJD are frivolous as well? Hmm...).
Or maybe there's actually a subtle reason why they exist, which you might notice if you break them. That's part of the learning process too
All best,
M


Java Regular Expressions
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Originally posted by Max Habibi:
Boy, I'm really tempted to ignore any post that starts with "Max's book sucks!', but I'm game
By and large, you need to remember Denny's DVDs was designed to be a teaching tool: it's designed to illicit exactly these sorts of questions. Do you really want to know what happens if the synchronization is removed? Trying removing it

Nothing happened? Maybe you're right, and the some of the synchronization in Denny's is frivolously(does this imply that the corresponding calls in certain versions of the SCJD are frivolous as well? Hmm...).
Or maybe there's actually a subtle reason why they exist, which you might notice if you break them. That's part of the learning process too
All best,
M

Hey Max. I did'nt mean to question the quality of the book. Its the BEST book for SCJD in my opinion, period.
Am sort of new to Java and trying to understand the details of each and every program, so curious to know. I thought if I understand every minute thing in the sample project, then that will make my assignment easy. So a little bit cuirous. Anyway, I will try to learn by playing with the code.
Thanks alot once again for the great book and for responding.
[ February 19, 2004: Message edited by: Satish Avadhanam ]
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Np, I was teasing
M
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,
I apologize if i appear to be becoming lazy; is it bad form not to completely
read through your post; if so, I'm sorry.
I also have not looked through all the code. But, I will take one part of the
above and comment on it to exercise my mind. Please keep in mind that
threading is tricky, and I can easily make a mistake in what I assert to be
true.
WARNING: this is not production quality code, but it is quite sufficient
to exercise one's mind in threading:
These few lines of code seem logically correct, so I assume that this is
not an exercise from the book where there are problems lurking with
the code:
I have changed method and variable names to make it easier to parse:
While it's true that you can certainly take things out of the code, and
by liberally applying the yield() method, attempt to get a failure, it
also is just as important to be able to look at the code and come to
a determination as to its correctness, since it is quite possible that
during testing you won't be able to create any noticable errors:

It is assumed that this lock() method is multithreaded. So, you need to ask
how the synchronization "binds" the logical lines of code together to prevent
another thread from interrupting the current thread and getting illogical
results.
So, between lines 3 and 4, if the current thread is paused, another thread
could come in and modify guardVector in some way that you don't anticipate
or don't want to happen. For instance, what if another thread removed
the target record number from the guardVector; then the thread that had
initially thought the target record was in the vector, would unnecessarily
wait(); this may or may not be critically important, you'd have to analyze
it more.
But, generally speaking, it makes logical sense to bind lines 3 and 4
together into a logical, atomic operation: a test on a vector which can't
change and then an action on a vector which didn't change. This is not
over synchronization.
Now, assume that the current thread is exiting the while loop and is now at
the comment line number 6. It's next job is to add a record number to the
vector. What happens if at line number 6 the current thread is spliced out
and another thread starts running. If the guardVector were not synchronized,
then another thread might add the same record number into the vector the
current thread was about to add; you might then have two threads thinking
they hold a lock on the same record (again, I have not written this down in
detailed proof, it is just an overview).
So, you have another logical binding: you don't want the object, the guardVector
to change during the steps that you decide it does not hold the record number
you wish to mutate, and the step that you actually add that record to the
guardVector.
In conclusion, the above is simply an example of multiple threads sharing an
object. If the current thread is basing any action on any assumption about this
shared object--such as it's current size, whether it contains this or that--
then you must synchronize the object for these two steps, these two steps
cannot have any other thread intervene:
synchronize (myObject) {
Step 1: Query object: i.e., "make assumptions before taking action"
Step 2: Take action based upon "these assumptions"
}
For a more detailed, step by step approach to learning about threads,
see Bruce Eckel's web site, his free online book:
Thinking in Java
Thanks,
Javini Javono
[ February 19, 2004: Message edited by: Javini Javono ]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,
Now, an interesting case occurs when you change the declaration of guardVector
from a Vector to an ArrayList. Let's investigate this, and see what happens;
keep in mind, please, that I may make errors in this preliminary examination.

Well, basically, the same logic applies as before. And, because we have
synchronized on the ArrayList guard, we are quite safely able to call the add()
method.
However, there is one caveat, and whether or not it is important depends on your
design, I think, but it is something to keep in mind.
Technically speaking, you could have other code which attempts to query or
mutate the ArrayList guard which does not synchronize on guard.
Then, the safety you see in the above method is an illusion, if you have not
carefully made sure that any usage of guard anywhere else did not
synchronize on guard!
So, this is a very interesting and subtle point! I find this quite interesting.
Basically, by declaring guard as a Vector, you have no second doubts! You
don't need to lose sleep with implementation details; you simply assert the
truth: no one should be accessing this guard unless that access is synchronized
on guard, and to make certain that I or anyone does not forget this, guard will
be a Vector.
As an example: if guard was an ArrayList, and you are using the add() method,
no one else should be manipulating the guard object; but, if another thread
is reading or writing to guard and has not synchronized on guard, you allow
a multi-threading error to occur.
Well coded, and surprising subtle!
Thanks,
Javini Javono
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi Javini, thanks for the detailed analysis and explaining. Actually in the original post I was talking about the synchronization of the methods and not the synchronization of the object in the lock metod. But you cleared me all regarding the object synchronization. That's great.
Appreaciate your help, thanks.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Locking issues in Max's book sample project - Denny's DVD store