【问题标题】:File lock between threads and processes线程和进程之间的文件锁
【发布时间】:2015-01-23 15:19:36
【问题描述】:

我正在编写一个程序,该程序从同一 JVM 上的不同线程和不同 JVM/进程写入单个文件。有没有办法为线程和进程锁定文件,这样无论有多少线程/进程尝试同时写入,一次只能写入 1 个?

目前我有类似于以下内容的内容,适用于锁定线程,但不适用于阻塞进程。如果我尝试在下面的实现之上使用FileLock,它会出现synchronized 停止工作。

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import scripts.com.adz.commons.utils.FileUtilities;

import java.io.*;

public class Foo {
    public static void main(String[] args) throws IOException {
        Bar bar = new Bar();
        bar.start();

        while (true) {
            FileUtilities.writeObjectToFile("C:\\test.html", "foo");
        }
    }
}

class Bar extends Thread {
    @Override
    public void run() {
        while (true) {
            try {
                FileUtilities.writeObjectToFile("C:\\test.html", "bar");
            } catch (IOException ignored) {}
        }
    }
}

class FileUtilitiess {
    private static final Object _lock = new Object();

    public static <T> T readObjectFromFile(File file) throws IOException, ClassNotFoundException {
        synchronized (_lock) {
            final byte[] bytes = FileUtils.readFileToByteArray(file);

            ByteArrayInputStream bis = null;
            ObjectInputStream ois = null;

            try {
                ois = new ObjectInputStream(bis = new ByteArrayInputStream(bytes));

                return (T) ois.readObject();
            } finally {
                IOUtils.closeQuietly(ois);
                IOUtils.closeQuietly(bis);
            }
        }
    }

    public static void writeObjectToFile(File file, Object object) throws IOException {
        System.out.println("Sent object: " + object.toString());
        synchronized (_lock) {
            System.out.println("Writing object: " + object.toString());

            ByteArrayOutputStream bos = null;
            ObjectOutputStream oos = null;

            try {
                oos = new ObjectOutputStream(bos = new ByteArrayOutputStream());
                oos.writeObject(object);

                FileUtils.writeByteArrayToFile(file, bos.toByteArray());

                // - Start: For testing lock.
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException ignored) {}
                // - End: For testing lock.
            } finally {
                IOUtils.closeQuietly(oos);
                IOUtils.closeQuietly(bos);
            }
        }
    }
}

【问题讨论】:

  • 你的意思是FileLock
  • FileLock 不适用于多线程:“它们不适合控制同一虚拟机内的多个线程对文件的访问。”
  • 显示带有FileLock 的代码;两者应该没有不能共存的理由。然而,我的直觉是,无论你试图解决什么问题,你都在使用错误的解决方案,如果你描述的是问题而不是你的实现,你可能会得到更好的答案。
  • 进程中的所有线程共享同一组文件锁。实际上,本机记录锁就是这样做的。 Java 只是利用了操作系统的能力。

标签: java multithreading file-io file-locking


【解决方案1】:

FileLockjavadoc

代表整个 Java 虚拟机持有文件锁。

这意味着在操作系统级别上,应用程序的不同线程将拥有访问锁定区域的相同权限。

要锁定来自不同线程的文件访问,您必须封装文件 IO 代码并强制同步执行。

【讨论】:

    猜你喜欢
    • 2014-12-03
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2015-10-29
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多