This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
While this method is reading a record in the for loop, there is some thread changes a record data that is already read. When this method returns the result that some record is not matched with the criteria. Is this occurrence acceptable? Should I implement as following code to eliminate dirty read?
Whatever you choose to do, remember this is a design choice, so it needs to go in your design choices document .
Personally if I were working on this assignment I would not worry about the potential for incorrect data being returned from this method:
This method is only returning an array of record numbers. Therefore you will have to read the records later anyway. Between the call to this method, and the call(s) to the read record, the data could have been modified anyway. So even if you prevent dirty reads here, your end result could still be that you are reading records which don't match.
Your server side requirements and your client side requirements may be different. Many people have server side requirements where the findXxx() method does a "starts with" search, while their client side has an "exact match" requirement. If your assignment has similar requirements then you are going to have to do additional validation client side anyway - that will remove any dirty data from your result set.
Even ignoring all that, your assignment (probably) does not have the concept of a read lock (and you probably don't want one either). So between the time you display a record and the time it is booked, the data may have changed. (Which brings us to another design decision - do you cater for that possibility ).
Note - these are just my thoughts. Others may have equally valid arguments for preventing the dirty read.
I do prefer your first solution, and agree (as most of the times ) with all Andrew's arguments. Except that you *do* prevent dirty reads already (a record cannot be written by some thread while another is reading it) and it's ... just perfect IMO.
You are doing a linear search through your records, so either of your solutions is good. However if you were doing a more sophisticated search algorithm the order of records might be important and you would want to use the code sample that synchronized over the whole for loop. This is the approach I would take.
Does anyone know if there is a significant performance penalty for acquiring the lock on an object repeatedly? (I know there is some performance penalty - otherwise every method would be synchronized.) In your first code sample you are reacquiring the lock each time through the loop. In your second code sample you only get the lock once. I'm guessing choosing the correct approach will be based on a number of factors - the total number of records, the number of expected threads, the threading strategy used by the VM (how often are threads swapped out), etc.
Joined: Jun 02, 2003
It's just a bet of mine, but the I/O envolved by reading a record should be much much slower than acquiring a lock. Surasak's solution 2 wouldn't scale at all, and that's why I did prefer solution 1.