I created a small Java servlet for a simple purpose: Once it is called, it will do the following steps:
- Read file foo.json from the local filesystem
- Process the data from the file and do some changes to it
- Write back the changes to the file
Simplified version of the code:
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FileInputStream inputStream = new FileInputStream("foo.json");
String filecontent = IOUtils.toString(inputStream);
inputStream.close();
JSONObject json = new JSONObject(filecontent);
doSomeChangesTo(json);
FileWriter writer = new FileWriter("foo.json");
writer.write(json.toJSONString());
writer.flush();
writer.close();
}
Now I am facing the problem that it could happen that the servlet is called nearly at the same time by two or more http requests to the servlet. To avoid multiple parallel write access on the same file I need to synchronize this somehow. From my understanding of the servlet lifecycle process, each request spawns a new thread, so using FileLock would probably have no affect:
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.
(From http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html)
I guess that using the synchronized(){}
keyword would also not work since I want to synchronize file system access and not access to variables/objects.
So, how can synchronize file system access in my servlet when multiple parallel requests on that servlet happen?
synchronized(){}
and that's it? – Hammersstatic final Object FILE_ACCES_LOCK = new Object()
, and wrap the code accessing the file insynchronized(FILE8ACCESS8LOCK) {}
– Maquis