Win a copy of Cross-Platform Desktop Applications: Using Node, Electron, and NW.js this week in the JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Multiple Execution of the Same Program Writing on the Same file  RSS feed

 
reus sickk
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I've got a problem with my program. An external system calls multiple times my program asking to write a line on the same file. The problem is when all the process is done the file has got less lines than I expected. I guess there is a concurrency problem. I've tried to lock the file by RandomAccessFile's Channel but I can't understand if doing so I can avoid completely the problem.

I've tried also to introduce a random Thread.sleep but it's not strong this solution.

Any suggestions? Are there different ways to do what I want?

Thanks in advance
 
K. Tsang
Bartender
Posts: 3648
16
Firefox Browser Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the ranch.

First what do you expect the resulting file looks like? Questions to ask are:
Are you trying to append data or overwrite data to that file?
If appending, is the file pointer at the correct place when you start writing (check the RandomAccessFile API)?

I doubt there are any issues with threads or concurrency in your case.
 
reus sickk
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have to append lines. The external system reads a table of elements and sends each row to my program that has to write the file. The first problem is that each call to my program creates a new instance of my program (consuming a lot of memory) and each call has to write the own line appending on the same file. If the external system reads 100 rows, the final file should have got 100 lines. I can't understand how solve this problem.
 
K. Tsang
Bartender
Posts: 3648
16
Firefox Browser Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes check the RandomAccessFile API, jump to the last file pointer before you write.
 
Rishi Shah
Ranch Hand
Posts: 43
Java Mac Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
K. Tsang wrote:Yes check the RandomAccessFile API, jump to the last file pointer before you write.


Expanding on this point, make sure you use #seek() and not #skipBytes().
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sounds dicey. If there are multiple JVM instances running this program at the same time, what would prevent the following scenario?

Process A sets position to end of file, let's say position 1234.
Process B sets position to end of file, again 1234.
Process A writes a record to position 1234. The new end of file is now later, let's say 1345.
Process B writes a record to position 1234, overwriting previous record.

It's one of the standard scenarios for concurrent threads, except since these are different processes, it's even harder to fix. There may be some guarantees somewhere in RandomAccessFile, or maybe FileChannel, that would fix this. But I don't see them, yet. I suspect this sort of thing is what's causing the problem seen by the original poster here. I'm not sure what the best solution is though.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From the FileChannel API:
A file channel that is open for writing may be in append mode, for example if it was obtained from a file-output stream that was created by invoking the FileOutputStream(File,boolean) constructor and passing true for the second parameter. In this mode each invocation of a relative write operation first advances the position to the end of the file and then writes the requested data. Whether the advancement of the position and the writing of the data are done in a single atomic operation is system-dependent and therefore unspecified.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And from FileChannel's lock() method:
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.

Sounds like it should work however for regulating competition between two different JVMs. However I would test this carefully to be sure; I seem to recall that locks on Windows can behave quite differently than locks on Mac. To test, try inserting a nice big Thread.sleep() in between setting the position and writing, and run a couple programs at the same time. That will make it easy for them to collide, if the locks allow them to collide.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!