Hi, We have a multi threaded java program. Multiple-threads will write to a file, and one thread will read from that file. I am looking for some design ideas. Is synchronization necessary?
I would consider synchronization in this case. Imagine that 2 threads (t1 and t2) open the file at the same time and start writing to it. The changes performed by the first thread are overwrited by the second thread because the second thread is the last to save the changes to the file. When a thread t1 is writing to the file, t2 must wait until t1 finishes it's task before it can open it.
Also, if you care about the latest possible update of the file, you should synchronize the writing threads with the thread that reads the file so that if there's any thread writing the the file, the reading thread should wait.
Once multiple Threads access shared data then Synchronization is necessary. If multiple threads write to the same file without some form of locking, then potentially you will end up with a lost update problem.
Reading is not as big an issue in all circumstances so you need to consider...if a thread is reading the file and at the same time another thread updates the file, does the reading thread need to know about the change? If so you need to lock the file for the reading thread also.
If you wanted multiple readers and one writer, you would be looking for a Read Write Lock or a Read Write Mutex.
But you want multiple writers and one reader. How do you know these writers won't overwrite each others data? Are they somehow segregated?
If being synchronous isn't important, you could have your writer running in its own thread, and allow other threads to queue up writes to the file. Although I think the first thing to consider is whether writing to a file is really what you want to do. Especially in high-traffic situations, having a lot of disk I/O may not be very efficient.
FileChannel is in theory thread safe. From the javadoc:
File channels are safe for use by multiple concurrent threads. The close method may be invoked at any time, as specified by the Channel interface. Only one operation that involves the channel's position or can change its file's size may be in progress at any given time; attempts to initiate a second such operation while the first is still in progress will block until the first operation completes. Other operations, in particular those that take an explicit position, may proceed concurrently; whether they in fact do so is dependent upon the underlying implementation and is therefore unspecified.
If you can use these, then you can use the built-in synchronization, rather than having to write your own.
Synchronization is necessary in this case. FileChannel is useful for preventing files being modified by processes outside the JVM: not so for applications which include multiple threads writing to a single file. From (further down in) the JavaDoc for FileChannel:
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.
See this post for a brief discussion of strategies to share file writing between threads.