Java Reference
In-Depth Information
It is important to realize that this is a compile-time validation only—it is still possible to
provide invalid data at runtime, resulting in a ClassCastException .
Line 143 calls a private method to read the DVD record based a location in a file. This
method is also used by our public method that will read a DVD based on a UPC number.
We will show the public getDVD method first:
172 public DVD getDvd(String upc) throws IOException {
173 log.entering("DvdFileAccess", "getDvd", upc);
174
175 recordNumbersLock.readLock().lock();
176 try {
177 // Determine where in the file this record should be.
178 // note: if this is null the record does not exist
179 Long locationInFile = recordNumbers.get(upc);
180 return (locationInFile != null) ? retrieveDvd(locationInFile)
181 : null;
182 } finally {
183 recordNumbersLock.readLock().unlock();
184 log.exiting("DvdFileAccess", "getDvd");
185 }
186 }
Line 175 requests a read lock on our mutex for the recordNumbers map. Remember that
many threads can be operating simultaneously, so asking for a read lock allows the other
threads to also gain read locks and work with the recordNumbers map.
If the UPC requested does not exist, null will be returned to the calling method, as
shown in line 181. Otherwise, the retrieveDvd method will be called in line 180 and the
results of that call will be returned to the calling method. If the retrieveDvd method throws
an IOException or a RuntimeException , it is important to ensure that we do not leave the
recordNumbersLock mutex locked, so we have put the call to unlock in the finally block at
line 183. It is important to remember that the finally block is still executed, even though the
return statement is at line 180.
196 private DVD retrieveDvd(long locationInFile) throws IOException {
197 log.entering("DvdFileAccess", "retrieveDvd", locationInFile);
198 final byte[] input = new byte[DVD.RECORD_LENGTH];
...
202 synchronized(database) {
203 database.seek(locationInFile);
204 database.readFully(input);
205 }
Multiple threads work with the recordNumbers map, but the majority of them will only be
reading the map, and multiple reads can occur simultaneously without affecting the other
threads. Therefore, access to the recordNumbers map is a perfect candidate for a ReadWriteLock .
However, in the case of reading from the data file, one thread could affect another thread
if they were allowed to operate simultaneously. When reading from the data file, we need to
perform two steps: move to the correct location in the file, then read the entire record. It is
very important that these two operations behave as a single atomic operation; otherwise, if
Search WWH ::




Custom Search