Synchronous write to same file using different file pointers

A

Alexander Dünisch

Hi newsgroup,

i have written a piece of code like the following:


// ======= start of code sample ===============

public void writeStuff(byte[] stuff, long location)
throws IOException {

RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
try {
raf.seek(location);
raf.write(stuff);
} finally {
raf.close();
}
}

// ======= end of code sample ===============


This function is being called by multiple threads.
Let's assume it can be guaranteed by the choice of value for location
and the length of array 'stuff', that one thread doesn't
overwrite the bytes written by another thread.

Because the RandomAccessFile is local to the method,
each thread would create it's own instance and use the associated
file pointer.

Can this be done safely or do i have to put the call to write in a
synchronized block?
In other words:
Can two or mor threads write synchronously to different locations of
the same file using different RandomAccessFile objects and thus
different file pointers, if there is no risk of one thread overwriting
another's data?

Thanks in advance for your answers.

Alex D.
 
K

Knute Johnson

Alexander said:
Hi newsgroup,

i have written a piece of code like the following:


// ======= start of code sample ===============

public void writeStuff(byte[] stuff, long location)
throws IOException {

RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
try {
raf.seek(location);
raf.write(stuff);
} finally {
raf.close();
}
}

// ======= end of code sample ===============


This function is being called by multiple threads.
Let's assume it can be guaranteed by the choice of value for location
and the length of array 'stuff', that one thread doesn't
overwrite the bytes written by another thread.

Because the RandomAccessFile is local to the method,
each thread would create it's own instance and use the associated
file pointer.

Can this be done safely or do i have to put the call to write in a
synchronized block?
In other words:
Can two or mor threads write synchronously to different locations of
the same file using different RandomAccessFile objects and thus
different file pointers, if there is no risk of one thread overwriting
another's data?

Thanks in advance for your answers.

Alex D.

Probably. There is one concern and that is that if two threads extended
the file you might get corrupted data. Also I don't think the
performance decrease by synchronizing would be all that great. The disk
is the slowest part of this and if by synchronizing you eliminated any
partial writes and the associated seeking it might actually go quicker.

I think I would synchronize and see if the performance is too poor. I
have running code that uses static methods with local RandomAccessFiles
and that use ReentrantReadWriteLocks to synchronize access. In my case
the rate of data access is probably well below that which would cause
great contention though.
 
C

Christian

Alexander said:
Hi newsgroup,

i have written a piece of code like the following:


// ======= start of code sample ===============

public void writeStuff(byte[] stuff, long location)
throws IOException {

RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
try {
raf.seek(location);
raf.write(stuff);
} finally {
raf.close();
}
}

// ======= end of code sample ===============


This function is being called by multiple threads.
Let's assume it can be guaranteed by the choice of value for location
and the length of array 'stuff', that one thread doesn't
overwrite the bytes written by another thread.

Because the RandomAccessFile is local to the method,
each thread would create it's own instance and use the associated
file pointer.

Can this be done safely or do i have to put the call to write in a
synchronized block?
In other words:
Can two or mor threads write synchronously to different locations of
the same file using different RandomAccessFile objects and thus
different file pointers, if there is no risk of one thread overwriting
another's data?

Thanks in advance for your answers.

Alex D.
I have done sth like this several times. And so far had no Problem.
Though don't expect two threads to see each others writes immediately if
you later might add reading. If you need real nice concurrency with
several threads writing on a single File you could simply give all
threads access to the same FileChannel object.
 
L

Leonard Milcin

Alexander said:
Hi newsgroup,

i have written a piece of code like the following:


// ======= start of code sample ===============

public void writeStuff(byte[] stuff, long location)
throws IOException {

RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");
try {
raf.seek(location);
raf.write(stuff);
} finally {
raf.close();
}
}

// ======= end of code sample ===============


This function is being called by multiple threads.
Let's assume it can be guaranteed by the choice of value for location
and the length of array 'stuff', that one thread doesn't
overwrite the bytes written by another thread.

Because the RandomAccessFile is local to the method,
each thread would create it's own instance and use the associated
file pointer.

Can this be done safely or do i have to put the call to write in a
synchronized block?

The answer isn't simple. For short writes under some specific number of
bytes (that will depend on the combination of OS/filesystem) you can
expect the writes to be atomic. I would recommend against using that
possibility. I'd write something to guard the access to that file that
would allow to queue writes that would then be performed synchronously.

Also, I don't think it's a good idea to open the file every time you
want to write something. Can't you just open the file (or the wrapper
class that would guard the access to the file) once, and then inject
that instance to all threads that want to use it?
In other words:
Can two or mor threads write synchronously to different locations of
the same file using different RandomAccessFile objects and thus
different file pointers, if there is no risk of one thread overwriting
another's data?

I've never done that but from what I know using NIO you can mmap a file
and then lock specific areas of that file before performing write
operations.
Thanks in advance for your answers.

You're welcome.

Regards,
Leonard
 
C

Chase Preuninger

I would just create a separate RandomAccessFile for each Thread. In
what you are saying there would be no point to multi-threading because
if only one thread can access the RAF at a time you might as well get
rid of the multi-threading.
 
A

Alexander Dünisch

If you need real nice concurrency with
several threads writing on a single File you could simply give all
threads access to the same FileChannel object.

This would certainly be the best approach.
Unfortunately, this is not an option for me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top