aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes RAF Threadsafe? 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 "RAF Threadsafe?" Watch "RAF Threadsafe?" New topic
Author

RAF Threadsafe?

Abdel Kader
Greenhorn

Joined: Apr 14, 2007
Posts: 11
I have used RandomAccessFile throughout my implementation of Data.java for the URLyBird but not without concern.

I dont want to open and close the file everytime I do read or write to the database so I create one and only one RAF object and keep the file open. The RAF is then closed in my overriding finialize method. Since the RAF was created using the "rwd" parameter is writes to disk continously and keeps the file up to date with the object.

However....
Accoring to some forums and bug-reports the RAF is not entirely thread safe, if thread safe at all... Nothing is written in the API so I simply ask anyone with the knowledge.

Too what extent is RAF Threadsafe? Or is my approach completely wrong?
Brian Kelly
Ranch Hand

Joined: Jan 04, 2007
Posts: 54
I didn't know that about RAF but I used it in SCJD and passed

Your locking mechanism should ensure that two seperate threads aren't writing to the same record at the same time.

I opened and closed my file for each read or write...keeps it simple...


SCJA, SCJP (1.4), SCJD
Abdel Kader
Greenhorn

Joined: Apr 14, 2007
Posts: 11
Ok I will follow your example mate :-)

I found this at sun:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4823133

It's from 2003 but still "in progress" and there are other thread safe related complaints about RAF as well.. so better safe than sorry - open a new RAF for every read and write.

Since the assignment state that I may assume that only one program is accessing the file it is very very very tempting to open and close the file only once in order to improve performance. But i guess a few words in choices.txt will make them understand...
David A. Scott
Ranch Hand

Joined: Apr 13, 2006
Posts: 55
I am only opening and closing the file once. This can easily be changed but I'd be interested in more discussion as to why this might be necessary.

ALL access to my single instance of RandomAccessFile is synchronized so only one thread can ever do anything to it at a time. Surely this makes it thread safe??
Abdel Kader
Greenhorn

Joined: Apr 14, 2007
Posts: 11
Yes, if all access is synchronized then it is threadsafe. However, if you wish to lock the db-file on a particular row like in the urlybird assignments, you will run into problem. For example it is known that the RAF.length is not thread safe and repositions the filepointer if you have multiple thread acceessing the file simultanously.

The reason why I started this topic is because I want to know if it is possible to use one single RAF and lock particular rows in a db-file rather than locking the entire file. This will fail if the RAF is not thread safe.
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Hi Guys

The RAF is not synchronized, if different threads access it, more precisely set the file pointer on different locations can be that you read/write from/on the wrong location. Take this example :
Thread A seek(100)
Thread B seek (300)
Thread A readByte
Thread A seek(1000)
Thread B readByte

If in your architecture your db file is accessed by more than one thread you must provide a synchronized access.

Abdel if you open the file for each transaction and you close it with a finalize method you will get a lot of open(unclosed) file handlers because you don't get a guarantee that the finalize method will run. This behavior can easily crash your application - because depending in the OS you can not have only a certain amount of open file (in the same time).
Why don't you try to keep the file open for the entire working session ?

Regards M


SCJP, SCJD, SCWCD, OCPJBCD
Abdel Kader
Greenhorn

Joined: Apr 14, 2007
Posts: 11
Mihai, my idea was not to open one RAF for every method. I wanted to open only one RAF for the entire db-file and use the same RAF for every method and then close it in finalize which is quaranteed to run once at least. The ide was to avoid opening and closing the file for every method. But since I discovered (and as you point out in your reply) that RAF is not threadsafe, this is no longer an option. Instead, now I create a new RAF object open and close the file in a finally-block for every method.

It is worth mentioning yet another time: RAF is NOT threadsafe. All access to the db-file must be synchronized or use an unique RAF object.
Tai Hu
Greenhorn

Joined: Apr 27, 2007
Posts: 9
I think as long as you synchronized your RandomAccessFile object each time you use it. It should be fine to have one RandomAccessFile object for whole Data class. Opening RAF for each method (update, create, and delete) could create too much open file handlers (Linux only allow 256 physical file handlers, Windows also has limitation but it is bigger). By the way, finalize() method is not guaranteed to be called.
Abdel Kader
Greenhorn

Joined: Apr 14, 2007
Posts: 11
Agreed, but you cannot synchronize your methods using the RAF AND allow record locking. If you synchronize the RAF methods you basically lock all records since other threads are not allowed to execute on other records.
Tai Hu
Greenhorn

Joined: Apr 27, 2007
Posts: 9
Yes, I knew. If I synchronized on a single RAF, I locked all the record. But I didn't see how a record based locking could be achieved. For update, delete, with lockCookie, it is ok to allow multiple threads to change data file at the same time. However, how do you handle create() method? Let's same there is one thread is creating a new record at the end of data file. Before it writes out all the bytes. There is another thread coming in for update() method. At that moment, your new RAF in update() method will open a partially completed file. I am not sure if RAF could handle this thing. Also as I mentioned before, you may need to keep a counter for all the opening RAF to limit the total number of file handler.
Mihai Radulescu
Ranch Hand

Joined: Sep 18, 2003
Posts: 916

Tai, there are two different stuff here :
1.the lock manager which ensures that nobody will alter a lock record
2.a synchronize access to the database file which ensure the database file integrity.

If you create a record you don't need to lock it (at least this is my opinion)
but you must be shore that the create record operation is atomic on the database file layer.

Regards,
M
[ May 05, 2007: Message edited by: Mihai Radulescu ]
rinke hoekstra
Ranch Hand

Joined: Apr 06, 2007
Posts: 152
I wouldn't bother openening and closing it each method. Why would you? I think it creates more overhead than it solves anything.

But now, just wondering: given the fact that, in my case, I have only one RandomAccessFile object in one server: is it even strictly needed to close it at all? I mean: while I have only one RAF object, then the only moment you would want to close it is when closing down the server application, and then the system resources will be freed anyway, isn't it? Or is that too "dirty" programming?

Abdel, About the "rwd" pattern you used at creation: is that necessary? Is "rw" not enough, provided that you have only one RandomAccessFile Object in one server instance??


_ _ ________________________ _ _ <br /> <br />Just SCJP (but 93%)
William Smith II
Ranch Hand

Joined: Apr 26, 2007
Posts: 39
I'm at a standstill in my assignment. I'm questioning the thread safety of RandomAccessFile as well. I've written a little multi-threaded tester for my Data class. When I use one thread, my Data class works perfectly. But when I have 2+ threads going, the output on the file is unpredictable and incorrect. The file ends up being corrupt because a record is written it a byte or two off, it writes out null values where a record should be, but other records look OK. It's very sporadic. So it's got to be a thread safety issue.

My Data tester uses one and only one Data object. The Data object creates the RandomAccessFile object in the constructor so there can only be one. My data tester basically implements runnable and takes Data as a parameter. I use a lock manager which I use on an update or create which is basically a Set. The lock manager is created as part of the Data object so again one and only one lock manager is created.

I've synchronized on RandomAccessFile and a host of other objects in the hopes of solving the problem but to no avail. It seems to me the file pointer may be getting changed between thread accesses despite RandomAccessFile being locked by a synchronized(raFile) { .. }

Anyone else having problems with RandomAccessFile and thread safety?
Ken Boyd
Ranch Hand

Joined: Dec 10, 2003
Posts: 329
Originally posted by William Smith II:
I'm at a standstill in my assignment. I'm questioning the thread safety of RandomAccessFile as well. I've written a little multi-threaded tester for my Data class. When I use one thread, my Data class works perfectly. But when I have 2+ threads going, the output on the file is unpredictable and incorrect. The file ends up being corrupt because a record is written it a byte or two off, it writes out null values where a record should be, but other records look OK. It's very sporadic. So it's got to be a thread safety issue.

My Data tester uses one and only one Data object. The Data object creates the RandomAccessFile object in the constructor so there can only be one. My data tester basically implements runnable and takes Data as a parameter. I use a lock manager which I use on an update or create which is basically a Set. The lock manager is created as part of the Data object so again one and only one lock manager is created.

I've synchronized on RandomAccessFile and a host of other objects in the hopes of solving the problem but to no avail. It seems to me the file pointer may be getting changed between thread accesses despite RandomAccessFile being locked by a synchronized(raFile) { .. }

Anyone else having problems with RandomAccessFile and thread safety?


When you are writing new record at the end of the file your db point move to different location make sure you have lock that part. Also you have to make sure where ever raf.seek is given synz that part. Also do the same for Map objects which hold record number and location of that number in map, so two threads can't get location of one record or get mix up and write somewhere else. Andrew's book will help you as well in this case.

Hope this helps.


SCJP, SCWCD, SCBCD, SCJD, BB Java2 and JSP1.1
William Smith II
Ranch Hand

Joined: Apr 26, 2007
Posts: 39
I use a RandomAccessObject as a member of my Data class. My Data class
is a singleton (or will be) and only one is created. I've written a
tester DataTestThread which I use to create 100 threads.

I've found that if I lock the Data object as part of my Runnable tester, then
the output file is created as expected.

But if I remove that and move make the update/create methods syncrhonized, or
say synchronized(this), the output file is becomes corrupt.

I think the methods should be synchronized internally (ie synchronized update()) and not
as part of the thread.

What is the difference? So long as I lock the Data object as part of the method
declaration, I should be OK, but I'm not. What am I missing or doing wrong?
It could be how I"ve written by Data tester, but not sure.


Here's my main of my tester noting that data is only created once.



And here's the first part of my DataTestThread:

[ June 04, 2007: Message edited by: William Smith II ]
William Smith II
Ranch Hand

Joined: Apr 26, 2007
Posts: 39
It turns out my concurrency problems may end up being my lock manager. I thought I had that part nailed down, but my locks don't seem to be being released.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: RAF Threadsafe?