Java 线程和进程之间的文件锁

Java 线程和进程之间的文件锁,java,multithreading,file-io,file-locking,Java,Multithreading,File Io,File Locking,我正在编写一个程序,从同一JVM上的不同线程和不同JVM/进程写入单个文件。是否有一种方法可以同时锁定线程和进程的文件,以便无论有多少线程/进程试图同时写入,一次只能有1个线程/进程写入 目前,我有一个类似于下面的东西,用于锁定线程,但不用于阻塞进程。如果我尝试在下面的实现之上使用FileLock,则synchronized将停止工作 import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; imp

我正在编写一个程序,从同一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);
            }
        }
    }
}
import org.apache.commons.io.FileUtils;
导入org.apache.commons.io.IOUtils;
导入scripts.com.adz.commons.utils.FileUtilities;
导入java.io.*;
公开课Foo{
公共静态void main(字符串[]args)引发IOException{
条形=新条形();
bar.start();
while(true){
FileUtilities.WriteObject文件(“C:\\test.html”、“foo”);
}
}
}
类栏扩展线程{
@凌驾
公开募捐{
while(true){
试一试{
FileUtilities.writeObjectToFile(“C:\\test.html”,“bar”);
}捕获(忽略IOException){}
}
}
}
类文件实用程序{
私有静态最终对象_lock=新对象();
公共静态T readObjectFromFile(文件文件)引发IOException,ClassNotFoundException{
已同步(_锁){
最终字节[]字节=FileUtils.readFileToByteArray(文件);
ByteArrayInputStream bis=null;
ObjectInputStream ois=null;
试一试{
ois=新的ObjectInputStream(bis=新的ByteArrayInputStream(字节));
返回(T)ois.readObject();
}最后{
IOUtils.closes(ois);
IOUtils.安静关闭(bis);
}
}
}
公共静态void writeObjectToFile(文件、对象对象)引发IOException{
System.out.println(“发送对象:+object.toString());
已同步(_锁){
System.out.println(“写入对象:+object.toString());
ByteArrayOutputStream bos=null;
ObjectOutputStream oos=null;
试一试{
oos=newobjectoutputstream(bos=newbytearrayoutputstream());
oos.writeObject(对象);
FileUtils.writeByteArrayFile(文件,bos.toByteArray());
//-启动:用于测试锁。
试一试{
睡眠(10000);
}catch(InterruptedException忽略){}
//-结束:用于测试锁。
}最后{
IOUtils.安静地关闭(oos);
IOUtils.安静关闭(bos);
}
}
}
}
请参见
文件锁

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

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


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

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