File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes [B&S] Thread safe access of db file Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "[B&S] Thread safe access of db file" Watch "[B&S] Thread safe access of db file" New topic
Author

[B&S] Thread safe access of db file

Russell Wurth
Greenhorn

Joined: Jul 12, 2004
Posts: 20
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!
Anton Golovin
Ranch Hand

Joined: Jul 02, 2004
Posts: 476
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 ]

Anton Golovin (anton.golovin@gmail.com) SCJP, SCJD, SCBCD, SCWCD, OCEJWSD, SCEA/OCMJEA [JEE certs from Sun/Oracle]
Russell Wurth
Greenhorn

Joined: Jul 12, 2004
Posts: 20
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

Joined: Jul 02, 2004
Posts: 476
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 ]
Julian Kennedy
Ranch Hand

Joined: Aug 02, 2004
Posts: 823
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
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: [B&S] Thread safe access of db file
 
Similar Threads
nx:All of URLy Bird1.1.3 about record lock
RandomAccessFile do not write!
Why the EOFException always thrown ?????
Test your business service
DBMain interface