The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
SCJP (1.4), SCWCD, SCJD
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
SCJP (1.4), SCWCD, SCJD
SCJP (1.4), SCWCD, SCJD
There is only one instance of DVDDatabase used.
..several instances of the DVDDatabase object can exist…
Andrew, I am going to try to articulate why the method level synchronization for the aforementioned methods may not be necessary. Here we go: Since we use multiple Data instance design where one Data instance is assigned to one client, we know that "different" clients will not clash with each other. Even though RMI does not guarantee "one" thread to execute the methods of an instance of the Data class, since each instance is isolated from the "other" executing instances and since the LOGICAL record level locking is implemented, we should not synchronize read, upate, delete, find, and create methods?
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Since there is only one instance of the DVDDatabase object, then the synchronization is a good thing.
But in Bharat's case where there will be more than one instance of the Data class, having the methods within the Data class synchronized will have a (minor) performance hit with no benefits.
From reading your comments it looks like you are saying that there is no need to make these public methods synchronized. Is this the route you will take?
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Some people have received an interface (for either hotel or contractors) with a lock() method that returns a cookie.
For these instructions, many people are planing on having only a single instance of the Data class (either via a Singleton or a Multiton).
Some people have received an interface (for either hotel or contractors) with a lock() method that does not return any identifier (return type = void).
For these instructions, many people are planing on having only one instance of Data class per connected client.
In this case, it makes no sense to synchronize the methods within Data.
By wrapping your method in a synchronized block, you are effectively treating the entire method as a single atomic operation, as far as other threads’ clients of that object are concerned.
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
Would you recommend me to change my design?
I would have to buy some Fosters and after waking up with big headaches redesign my thread safety concepts
Andrew, you australians are really amazing, I think that's really popular in Down Under to travel around the world, isn't it? But you have so good beers in Australia too
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
I will synchronize on the WeakHashMap whenever I want to do a read or a write ... It should be okay, shouldn?t it?
Also, there would be no need to have the writeFixedString and readFixedString methods synchronized if they are called from a synchronized context. Is this correct?
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
I have been busy and it is time for Andrew to take charge.
I seem to have reached my current limits here.
We are awaiting your response, please give some exampes with code snippets.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Your earlier code had static synchronized methods in DataHelper. Therefore these methods would have synchronized on DataHelper.class - of which only one instance can ever occur, so you already worked with the suggestion I had made: "Have a single instance of a helper class which does the disk operations, in which case it's methods could be synchronized, alleviating your concerns".
So you should have already been fine. Your writeFixedString() should already have been treated as an atomic operation.
Have a single instance of the file I/O class (RAF, or NIO, or ...), and have a synchronized block based on that single instance, in which the seek and read or update methods are treated as an atomic operation.
it probably also blocks other threads from obtaining locks while you are doing reads / writes which is an undesirable side effect
Bleagh. Well if you are going to drink that Fosters crap then it is no wonder you will wake up with a big headache. There's a reason it is so plentiful in Europe - we don't want it in Australia, so we export it every chance we can. With so many excellent wheat beers in Gemany and so many other good beers from Holland and Belgium I don't know why you would even look twice at Fosters. I certainly didn't have a single Fosters while I was in Europe. Now if you ever get a chance to try some Cascade (from Tasmania) you will know what a really good Australian beer is like. And I have never heard of anyone getting a headache after drinking it - it is made from very pure water and pure ingredients.
Hope the exam went well!
I do have a single instance of randomAccessFile object which is created in the singleton DataSchema file. A handle on this file is passed to all the Data objects that are created. This would, in my opinion, be a more logical object (i.e. the randomAccessFile object) to synchronize on when doing the reading and writing, rather than the lockedRecords object.
I am not sure if this method is any better (efficient etc) than synchronizing on the lockedRecords object, maybe you could give me your opinion on it.
the reason you want to lock a record is because you wish to do a read or a write, therefore you have to wait until the randomAccessFile is nolonger locked anyways.
If the method of locking the randomAccessFile sounds ok, I may go with this as, stated above, it sounds more logical to lock on the file rather than the lockedRecords object (even though it may not make a lot of difference).
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Ooh, good to know, I will try to get some Cascade, I'm now really curious
![]()
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
If we have a singleton instance of the DataScema class that creates the RAF, passes its handle to the requesting Data instances, and synchronize on the ReadFixedString and WriteFixedString methods of the DataHelper classes which are also static, we should be OK.
3. Dirty reads are OK. Therefore only logically record lock before reading a record?
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
John, you were astute enough to ignore my posts and focus on Andrew's.
I think I have finally come home from around the block only after having gone around the world in the process of doing it.
You need to follow the same synchronization logic for the "write" operations as well, i.e., synchronize on the randomAccessFile for the create/update method same as you are doing for the write methods.
And you should remove the synchronization from your readFixedString / writeFixedString methods.
Hello Andrew,
We are eagerly awaiting your response.
Ulrich: my write method looks like:
John: Just to double check, when you said the following:
John: 2. In fact anywhere I do a randomAccessFile.seek I would need to synchronize the block following it ? e.g. my private inValidRecord method does a seek() followed by a readByte(), so this would need such a synchronized block as well?
John: 3. The isValidRecord is also called by the three functions which are involved in record locking (lock, unlock and isLocked). I presume also there is no problem here i.e. two synchronizations take place when lock, for example, is called ? one in inValidRecord and one further down, they are not nested however. Is this ok?
John: 4. In the find method I do a .... Is this mechanism is okay?
Bharat: would you please define the word "mutex" for me? I think of mutants as in the X-men movie and that has a rather negative effect in my efforts to understand what you are explaining above.
Bharat: We are eagerly awaiting your response.
John: Yes hopefully Andrew can give us some feedback.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
What did I say, and what is your question?
You only need to lock the record for writing not for reading.
Why are you synchronising the find method though? What does it gain you? Or, more importantly, what does it cost you?
You are converting from String into an array of bytes using the platform's default charset. Do you think this meets the US-ASCII / 7 bit requirement?
The character encoding is 8-bit US ASCII
Why skip the deleted flag? If you assume that any write is only going to occur for valid records, then you can always set the deleted flag to "undeleted" (or whatever you call it).
Then your writeRecord() method can be used for adding a record as well.
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
Best of luck with your master's program.
Is this similar to the way you have implemented your read-method?
a:How have you guys implemented the validate(recNo)-method. I mean have you integrated the control of existence and deletion in validate() or split like I have done it above?
And if you have both control mechanisms in validate() how have you implemented the deletion control? (Reading of delete-flag at the disk or Caching the deleted Records?)
Jim, your code above, the inValidRecord(recNo)-method shouldn't be included in the synchronized block for reasons of integrity of the Record?
SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
John anytime I read a record I do not need to lock it ..., but within the read() method of Data.java I need to wrap part of it ... in a synchronized block to make sure the pointer does not get moved to the incorrect location in the middle of reading a record. I presume what I said here is correct and that this code is all right, is it?
John What advice would you give [regarding records being created in the middle of doing a find]?
John 3. Regardless of synchronizing or not in the find() method, scenarios [where the data returned from the read() does not match the criteria specified in the find()] may arise [, resulting in the wrong data being displayed] on the screen! Is this acceptable?
Ulrich So the right call would be:
Bharat I will be happy to buy all of you a beer if you are in the Boston, Massachusetts area. My recommendation? Sam Adams and Coors Light.
Ulrich public String[] readRecord(long recNo) throws IOException, RecordNotFoundException{
Ulrich
Ulrich
UlrichHere are my questions:
John I do not wrap the inValidRecord() record inside the synchronized block of the read(), update() etc methods ? I suppose you could do it. The reason I don?t is that I want to wrap as little of code as possible inside the synchronized block. Maybe Andrew or Bharat or indeed your good self will let me know if this is a good principle or not!
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
I just got through going through your post. Ulrich, it seems to me that you have gotten two cocepts related to locking mixed up. lock, unlock, and islocked methods perform the logical record level locking. You can use whatever concept you want to achieve this: people are using lock-manager, WeakHashMap (yours truly), HashSet coupled with a vector etc. Regardless of the data-structures being used, you have to account for a particular record being worked on using these three methods: lock, unlock, and islocked. The purpose of logical record locking is to inform other threads/clients that this particular record is locked currently and should be considered off-limits until further notification.
The purpose of synchronizing the RAF file-pointer is entirely different. Since the same file pointer is being used by different clients (remember it is defined in the DataSchema class which is designed to be a Singleton), it can be moved around unintentionally by competing threads which are working on different records. If we don't synchronize to make sure that the file-pointer moves as we wish, i.e., read or write entire physical records, we will end-up with getting weird data which is an unpredictable mixture of bytes from different records of the RandomAccessFile.
Mutex is a shortening of "Mutual exclusion" - a mutual (common) device which allows one client access to something, while excluding all others. So the object you synchronize on becomes a mutex.
Don't get me started about those stupid light bulbs. |