• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

[B&S] Thread safe access of db file

 
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Although the NIO package is not documented as unallowed in my instructions.html file, I was not planning on using it. I recieved no response from Sun regarding it's usage for my project.

My design uses a singleton DBFileAccess class that will be called by the server for read/write operations requested to the server by the object. I open a single RandomAccessFile for my database file, and I am planning on synchronizing on the RAF object for any read or write method call.

I wrote a test application to create threads to read a random row from a predetermined set of rows and compare the results with what should be there in order to ensure that the read is completed correctly. I put a random thread sleep in critical portions of the read in order to ensure that no other thread will interrupt. Here is a sample:


This appears to work with my test program, creating 50k threads to read and no read errors.

My question is this: Are there any other ways to control multiple threads accessing my file, so that the construction of the data from the byte array is not interrupted? I am assuming that since I am synchronizing on myRAF, that a read and an update will not occur at the same time. My only complaint with this design is the performance does not appear to be very good, but probably good enough for SCJD.

Thanks!
 
Ranch Hand
Posts: 531
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
LOCKING.

This is code from my assignment:

public class Data implements DB {
private static HashMap lockedDBRecords = null;
...
}

I would attempt to make thread-safe access like this:

1) make Data class thread-safe.
2) make static HashMap in the Data class thread-safe.
2) put logical locks into the HashMap in the Data class.

That way your thread will have to do exactly this:

i) LOCK()

1) Acquire lock on the Data object. Wait() if necessary.
2) Acquire lock on the HashMap. Wait() if necessary.
3) Put a logical lock into the HashMap.
4) Release lock on the HashMap. (let other threads lock other records)
5) Release lock on the Data object. (let other threads do some work)

ii) OTHERMETHODSOFDATACLASSEXCEPTUNLOCK()

6) Acquire lock on the Data object. Wait() if necessary.
7) Run the body of the method you called. Write, read to the dbFile
with thread safety assured.
8) Release lock on the Data object. (let other threads do some work)

iii) UNLOCK()

9) Acquire lock on the Data object. Wait() if necessary.
10) Acquire lock on the static HashMap. Wait() if necessary.
11) Unlock record (remove from HashMap.)
12) Release lock on the static Hashmap.
13) Release lock on the Data object.

Every thread will do this in the exact same order. There is no reverse-nesting, so there will not be any deadlock. Everything is synchronized except atomic data, so there is no race conditions.

Insofar as the question of using NIO, it renders record locking obsolete. If writes and reads are done atomically, then record locking is unnecessary. Hence I do not believe it is permitted.

Additionally, what would be the purpose of locking if RAF is to be synchronized? If it is synchronized, writes and reads will be atomic no matter what and no opportunity to corrupt the dbFile will take place.

Record locking is necessary if atomic reads/writes cannot be assured.
[ July 29, 2004: Message edited by: Anton Golovin ]
 
Russell Wurth
Greenhorn
Posts: 20
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Anton,

Are you implementing a single Data class? I was going to have an instance of a Data object per client that send it's read/update data/book/unbook commands to the server

Are you suggesting a lock for each read? I was only going to lock/unlock in a map for any writing that needs to go to the file.

Russell
 
Anton Golovin
Ranch Hand
Posts: 531
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Russell Wurth:
Anton,

Are you implementing a single Data class? I was going to have an instance of a Data object per client that send it's read/update data/book/unbook commands to the server

Are you suggesting a lock for each read? I was only going to lock/unlock in a map for any writing that needs to go to the file.

Russell



I was thinking about implementing a Data object per client thread on the server, but then I realized I would have to enable file locking for that to work, and file locking obviates record locking since it makes for atomic writes and reads.

So now I am thinking about implementing only one Data object on the server.

A client would call a DataImpl object, which would pass the request to DataAdapter object (which would mask the way Data object works) which would call the methods of the Data object. There would be many DataImpl objects and many DataAdapter objects, but only one Data object (synchronized.)

Yep, I would implement a lock for read also. But it depends. If you are going to synchronize on the file itself during write/read, then record locking kind of becomes a moot point, since you are assuring atomic read/write anyway. The purpose of record locking with IO facilities is to prevent other threads which cut in from modifying the same record. IO is not guaranteed for atomic write/read.

The reason NIO is not permitted on this assignment is that it obviates record locking as a concept.

With IO, you can have thread A start writing to a record and thread B cuts in and modifies the same record, for instance. IO does not guarantee atomic writes. With record locking, thread B will never get a chance to write to the same record as thread A because it will be waiting for the record to be unlocked at the HashMap.
[ July 29, 2004: Message edited by: Anton Golovin ]
 
Ranch Hand
Posts: 823
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi folks,

I haven't read the whole thread as there's rather a lot of it and it seems quite complex.

In broad terms, I would suggest tackling the problem stated initially by implementing locking at the record level for any write operations, whilst allowing reads at any time. This is equivalent to the default transaction isolation on most popular RDBMS, termed "read committed" (if you're familiar with that concept). While an implementation which locks at the file level may be sufficient to pass SCJD it is unlikely to achieve full marks for that section.

Hope this helps.

Jules
 
Politics n. Poly "many" + ticks "blood sucking insects". Tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic