I created a small Java servlet for a simple purpose: as soon as it is called, it will follow these steps:
- Read the file foo.json from the local file system
- Process data from a file and make some changes to it
- Write 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 faced with a problem that it may happen that a servlet is called almost simultaneously two or more HTTP requests to the servlet. To avoid multiple concurrent access to the record in the same file, I need to somehow synchronize it. From my understanding of the servlet life cycle process, each request spawns a new thread, so using FileLock will probably not affect:
File locks are stored 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 assume that using the synchronized(){} keyword will not work either, since I want to synchronize access to the file system and not have access to variables / objects.
So, how do I synchronize access to the file system in my servlet when there are several concurrent requests on this servlet?
source share