Do I have to synchronize access to the seek, read and write-methods? Or do you advise to create a new instance of the RandomAccessFile reading my database file in each method of my Data class (create, update, delete)?

Thanks Daniel

Alex Belisle Turcot

Ranch Hand

Posts: 516

posted 8 years ago

Originally posted by Daniel Haupt: Hi folks,

I've implemented my Data-Class and the locking mechanism as well so far, the JUnit-Tests posted some where in this forum perform fine as well.

I've still got a question according the RandomAccessFile class. Is it threadsafe?

Currently the RandomAccessFile is a instance member of my Data class?

Do I have to synchronize access to the seek, read and write-methods? Or do you advise to create a new instance of the RandomAccessFile reading my database file in each method of my Data class (create, update, delete)?

I would personally recommend to create a new instance as a local variable in each method. I find it to be the simplest and best way to ensure that only a single thread is using a specific file pointer at a time.

Even concurrent read might become a problem if you use a single Member variable RandomAccessFile. You need to synchronize, but then not much of concurrent read. Perhaps someone who used a member variable RandomAccessFile could explain why it could be good idea

Well, I agree with Alex here. I think the best approach is to use a local variable in each method. This is what I did too. And also, my Data class is a singleton, and all its methods are synchronized, so we can guarantee that no more than 1 thread is reading/writing to the file at a time. I know that it may cause some I/O overhead, but at least it is guaranteed that the file is always in a good shape.

Originally posted by Roberto Perillo: And also, my Data class is a singleton, and all its methods are synchronized, so we can guarantee that no more than 1 thread is reading/writing to the file at a time.

Hi,

did your instructions come with synchronized methods ? You are currently not providing concurrent read as (most probably) requires your assignment.. Also, all your methods being synchronized, wouldn't it be pretty much the same as synchronizing on a single member variable RAF..

did your instructions come with synchronized methods ? You are currently not providing concurrent read as (most probably) requires your assignment..

Well, the instructions didn't come with synchronized methods, but, like unchecked exception, you can add that to your method. Also, I re-read the requirements, and the only part that it mentions concurrency is this one:

"Your server must be capable of handling multiple concurrent requests, and as part of this capability, must provide locking functionality as specified in the interface provided above. You may assume that at any moment, at most one program is accessing the database file; therefore your locking system only needs to be concerned with multiple concurrent clients of your server."

So, as far as I can understand, it means that there are going to be 1 - N clients accessing the server at a time. The challenge is to deal with this concurrency. How the reading of the database is done is "transparent" to the client; so, let's say, if 2 clients perform a search at the same time, it will look like they got the data at the same time, but actually, one got before the other one. I decided to take this approach to avoid any kind of mess in the .db file.

Also, all your methods being synchronized, wouldn't it be pretty much the same as synchronizing on a single member variable RAF..

Hum... almost. When you first instantiate a RandomAccessFile object, you are ready to read the file. But, I was thinking... when do we get to close the file? Probably when the application is closed... so, when it happens, we could call a close() method... the problem is, the interface doesn't have this method, so this:

DBMain dataHandler = new Data(); dataHandler.close();

wouldn't work. Also, one good practice is to keep the scope of variables as "restrict" as possible. So, I thought that having a local variable instead of having a class variable would be better.

I re-read that part in the requirements, and I you are right, they never explicitly say that read must be concurrent..

However, from the sentence you quoted:

Your server must be capable of handling multiple concurrent requests, and as part of this capability, must provide locking functionality as specified in the interface provided above. You may assume that at any moment, at most one program is accessing the database file; therefore your locking system only needs to be concerned with multiple concurrent clients of your server. Any attempt to lock a resource that is already locked should cause the current thread to give up the CPU, consuming no CPU cycles until the desired resource becomes available."

They refer to the locking method of the Interface

Locks a record so that it can only be updated or deleted by this client. If the specified record is already locked, the current thread gives up the CPU and consumes no CPU cycles until the record is unlocked.

I interpreted all this as if, making all the thread wait (synchronizing) was not "handling multiple concurrent requests", and since the locking description does not care about read, it should be possible to perform it seamlessly in parallel. That's how I understood it.

But again, I agree when reading it (now) that they never explicitly mention it.

What do other ranchers think about that ? Is that actually a requirement to allow concurrent read ?

Regards, Alex

Srini Madireddy

Greenhorn

Posts: 8

posted 8 years ago

Initially i was creating one random access file for each client and had thread safety issues. After reading this thread, i have changed my logic by creating a random access file in each method. now my code is behaving the way i wanted. Thanks for Alex,Robert. [ May 30, 2008: Message edited by: Srini Madireddy ]