java - 如何在 Java servlet 中同步文件访问?

标签 java file concurrency synchronized filelock

出于一个简单的目的,我创建了一个小型 Java servlet:调用它后,它将执行以下步骤:

  1. 从本地文件系统读取文件 foo.json
  2. 处理文件中的数据并对其进行一些更改
  3. 将修改写回文件

代码的简化版本:

@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();
}

现在我面临的问题是,两个或多个对 servlet 的 http 请求几乎同时调用 servlet。为了避免对同一个文件进行多次并行写入访问,我需要以某种方式对其进行同步。根据我对 servlet 生命周期过程的理解,每个请求都会产生一个新线程,因此使用 FileLock 可能不会有任何影响:

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.

(来自http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html)

我想使用 synchronized(){} 关键字也不起作用,因为我想同步文件系统访问而不是对变量/对象的访问。

那么,当多个并行请求发生在我的 servlet 上时,如何同步我的 servlet 中的文件系统访问?

最佳答案

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.

使用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)) {
               ....
            }
         }
      }
 }

关于java - 如何在 Java servlet 中同步文件访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25548192/

相关文章:

python - 希望写入单独的文件; python :

java - 如何从rtf文档文件的文件列表中获取InputStream?

java - 如何创建ArrayList的ArrayList,使其符合程序接口(interface)原则

java - 为什么未填充此数组?

java - 在 Java 8 中收集到 HashMap 到 LinkedHashMap

java - 迭代这些 ArrayList 的更好方法?

java - 如何在不使用包的情况下识别给定路径是Java中的文件还是目录?

java - 这个线程程序每次都会向我显示不同的答案

python - RQ 与 supervisord 并发?

.net - 使用 .Net 4 & Concurrent Collections 缓存超时