Every time a page is requested on my website, I log some details with a service call like this:
logService.logPageRequest(session, request, contentId);
This service call makes use of a static FileUtils (my own) method to do the actual update on the file.
public static void appendToTextFile(String string, String fileRootDirectory, String subdirectory, String filename, boolean startOnNewLine) throws Exception {
// code irrelevant to the question removed
String filePath=fileDirectory+"/"+filename;
File file=new File(filePath);
if(file.exists()) {
FileWriter out = new FileWriter(filePath, true);
if(startOnNewLine) {
out.write("\r\n");
}
out.write(string);
out.close();
} else {
FileWriter out = new FileWriter(filePath);
out.write(string);
out.close();
}
Every so often (let’s say scheduled every 15 minutes), I execute another service which renames this file and starts processing it.
I’d like to understand how I can go about ensuring that both concurrent writes are safe and rename is not executed while a write is in the process. I guess the answer will be some form of synchronization.
The two services need to share a synchronization object: it can be anything (even
new byte[1]) but it must be the one and same instance, passed into your “services”. Whenever there is a critical section, which means part of a code which wants to operate on a shared resource, it needs to be wrapped inThe rule of good locking is to know deterministically what are you locking, what is exactly the shared resource. What will kill you (and introduce deadlocks) is random adding of synchronized blocks in hope of “solving”. In your particular example, it’s most probably the actions on
file: just actions, not the operations on filename strings, neither the instantiation ofFile: you can have manyFileobjects pointing to the same file on disk and it’s not a critical operation, as long as it does not touch the disk yet. So i would saySimilarly, protect the
Fileactions in your other service. Keep in mind that it’s notFileobject you are protecting, but the file itself.