Tim*_*imo 5 java concurrency file synchronized filelock
我为一个简单的目的创建了一个小型Java servlet:一旦调用它,它将执行以下步骤:
简化版代码:
@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();
}
Run Code Online (Sandbox Code Playgroud)
现在我面临的问题是,几乎可以通过两个或多个对servlet的http请求来调用servlet.为了避免对同一文件进行多次并行写访问,我需要以某种方式同步它.根据我对servlet生命周期过程的理解,每个请求都会生成一个新线程,因此使用FileLock可能没有任何影响:
文件锁代表整个Java虚拟机.它们不适合控制同一虚拟机中多个线程对文件的访问.
(来自http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html)
我想使用synchronized(){}关键字也不起作用,因为我想同步文件系统访问而不是访问变量/对象.
那么,当该servlet上发生多个并行请求时,如何在我的servlet中同步文件系统访问?
我想使用
synchronized(){}关键字也不起作用,因为我想同步文件系统访问而不是访问变量/对象.
使用synchronized可以工作.您假设如果要控制从多个线程对对象X的访问,则必须synchronized在该对象上使用.你没有.您可以synchronized在任何对象上使用,前提是所有访问都使用相同的对象.
实际上,通常最好使用单独的private锁对象进行同步,因为类之外的代码不可能在锁上进行同步.
所以,你可能有这样的东西,每个共享文件有一个实例:
public class SharedFile
{
private final File path;
private final Object lock = new Object();
public SharedFile(File path) {
this.path = path;
}
public void process(.....) throws IOException {
synchronized(lock) {
try(InputStream = new FileInputStream(path)) {
....
}
}
}
}
Run Code Online (Sandbox Code Playgroud)