为什么我可以在java中打开两次相同的文件

时间:2013-10-25 13:16:43

标签: java winapi mutex

我想保护我的代码不要同时在目录中做同样的事情,我需要一种跨进程的互斥锁。由于有问题的目录最终可能会通过网络共享,我虽然打开了一个文件来写这种锁。

public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    try {
        FileOutputStream fos = new FileOutputStream("lockfile", false);
        try {
            System.out.println("Lock obtained. Enter to exit");
            br.readLine();
            System.out.println("Done");
        }
        finally {
            fos.close();
        }
    } catch (FileNotFoundException ex) {
        System.out.println("No luck - file locked.");
    }
}

两次成功运行java -jar dist\LockFileTest.jar! - 我看到两个控制台提示输入。

我也试过了new RandomAccessFile("lockfile", "rw"),效果相同。

背景:windows xp,32bit,jre1.5。

我的错误在哪里?怎么可能?

2 个答案:

答案 0 :(得分:2)

你试过FileLock吗?

RandomAccessFile randomAccessFile = new RandomAccessFile("lockfile", "rw");
FileChannel channel = randomAccessFile.getChannel();
FileLock lock = channel.lock();

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
    OutputStream fos = Channels.newOutputStream(channel);
    try {
        System.out.println("Lock obtained. Enter to exit");
        br.readLine();
        System.out.println("Done");
    } finally {
        fos.close();
    }
} catch (FileNotFoundException ex) {
}

答案 1 :(得分:0)

以这种方式使用FileOutputStream和/或RandomAccessFile不会让你锁定文件..

相反,您应该使用RandomAccessFile并获取FileChannel,然后对文件发出锁定..

以下是您修改的示例:

public static void main(String[] args)throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            RandomAccessFile raf = new RandomAccessFile(new File("d:/lockfile"), "rw");

            System.out.println("Requesting File Lock");
            FileChannel fileChannel = raf.getChannel();
            fileChannel.lock();
            try {
                System.out.println("Lock obtained. Enter to exit");
                br.readLine();
                System.out.println("Done");
            } finally {
                fileChannel.close();
            }
        } catch (FileNotFoundException ex) {
            System.out.println("No luck - file locked.");
        }
    }