Win a copy of Testing JavaScript Applications this week in the HTML Pages with CSS and JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

B&S 2.2.1 howto prevent nested locking

 
Ranch Hand
Posts: 100
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everybody,

I am currently working on my locking solution for the B&S v2.2.1 assignment.

At startup time I read all records in a Map using a RAF. When the application runs all records are read from the map. If a user adds, updates, or deletes a record this is reflected in the map, and also directly in the data file using a RAF. I am using the Map as a caching mechanism to allow for fast reading / searching of the records. Locking of the map is done using a ReadWriteLock, access to the RAF is safeguarded by synchronizing on this RAF object when performing read and write operations using this RAF.

Logical locking is done using a Map which stores both the record numbers and the associated lock cookie value. Access to this map is safeguarded using a Lock object. However, I am not sure if this is needed.

Now regarding my locking solution: I am using a Facade which makes sure that all update & delete operations are done in the following sequence:
- lockRecord
- update / delete
- unlockRecord

I am stuck with my lockRecord method (everything else is implemented), this is the problem:
The interface of Sun states that I have to throw a RecordNotFound exception from the lockRecord methods if the given record number is not found. If I want to check if the record exist (using my cache Map) I think I have to get a readLock for this map.


After this check I perform the locking:


However, I am not sure if this will work. Please consider the following case: Client A wants to update record #1, Client B wants to delete record #1.

Client A locks record #1, the lockRecord method checks if this record is present (which succeeds). After this the Client A thread is put on hold for Client B. Client B also wants to lock record #1, it also checks if it is present (which succeeds), after which it obtains the lock, deletes the record, and unlocks the record.
Now the Client A thread is resumed which locks record #1 while it is no longer there...

If I keep the map of records locked while waiting for my logical lock on record #1 I think I will be introducing possible deadlock, because it would result in nested locking:
[1] - lock the records map (read lock)
[2] - check if record exists
[3] - lock the logical locks map
[4] - check if we can get lock (if not wait until we can)
[5] - lock record #1
[6] - release lock on logical map
[7] - release lock on records map

Is there another way that I should go with respect to these locking issues?

I am sorry if this became a rather long post, however making it shorter would not give you all the needed information.

Best regards,
Jethro
 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jethro,

I also have B&S and designed the locking part the same as you are doing.

You must insert the code that checks for contractor's existance after exiting the while loop:

long cookie = System.nanoTime();
this.locksMapLock.lock();
try {
// Wait for the record to become unlocked.
while (this.locks.containsKey(recNo)) {
try {
this.lockReleased.await();
} catch (InterruptedException e) {
logger.log(Level.INFO, "Waiting on locks map interrupted.",
e);
}
}

// Check if record exists.
try {
this.recordsLock.readLock().lock();

// Check if the given record is present.
if (!this.records.containsKey(recNo)) {
throw new RecordNotFoundException(
"There is no record with number " + recNo);
}
} finally {
this.recordsLock.readLock().unlock();
}

this.locks.put(recNo, cookie);
} finally {
this.locksMapLock.unlock();
}

I added a private method that checks for the contractor's existance, because it is called from other parts too: delete(), update()
 
I don't always make ads but when I do they're tiny
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic