在单个 JVM 内和跨多个 JVM 使用 java 文件锁 [英] Using java file locks within single JVM and across multiple JVMs

查看:60
本文介绍了在单个 JVM 内和跨多个 JVM 使用 java 文件锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我错过了一些东西,但我无法理解文件锁在 Java 中的工作原理.更准确地说 - 它是如何实施的.

I guess I miss something, but I cannot understand how file locks work in Java. To be more exact - how it is implemented.

似乎我无法在单个 JVM 中为同一个文件获取(甚至无法尝试获取)两个或多个锁.将成功获取第一个锁,所有进一步尝试获取更多锁都将导致 OverlapingFileLockException.尽管如此,它适用于单独的进程.

It seems I cannot acquire (even cannot attempt acquiring) two or more locks for the same file inside single JVM. First lock will be successfully acquired, all further attempts to acquire more locks will result in OverlapingFileLockException. Nevertheless it works for separate processes.

我想实现由文件系统支持的数据存储,旨在处理多个并发请求(读取和写入).我想使用文件锁来锁定存储中的特定文件.

I want to implement data-storage backed by file-system which is intended to work with multiple concurrent requests (both read and write). I want to use file locks to lock on particular files in the storage.

看来我必须在 JVM 级别再引入一个同步(独占),然后才同步文件以避免此异常.

It seems that I have to introduce one more synchronization (exclusive) on JVM-level and only then sync on files to avoid this exception.

有人做过这样的事吗?

我准备了简单的测试用例来说明我的问题所在.我使用 Mac OS X、Java 6.

I prepared simple test case to show what my problem is. I use Mac OS X, Java 6.

import junit.framework.*;

import javax.swing.*;
import java.io.*;
import java.nio.channels.*;

/**
 * Java file locks test.
 */
public class FileLocksTest extends TestCase {
    /** File path (on Windows file will be created under the root directory of the current drive). */
    private static final String LOCK_FILE_PATH = "/test-java-file-lock-tmp.bin";

    /**
     * @throws Exception If failed.
     */
    public void testWriteLocks() throws Exception {
        final File file = new File(LOCK_FILE_PATH);

        file.createNewFile();

        RandomAccessFile raf = new RandomAccessFile(file, "rw");

        System.out.println("Getting lock...");

        FileLock lock = raf.getChannel().lock();

        System.out.println("Obtained lock: " + lock);

        Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                try {
                    RandomAccessFile raf = new RandomAccessFile(file, "rw");

                    System.out.println("Getting lock (parallel thread)...");

                    FileLock lock = raf.getChannel().lock();

                    System.out.println("Obtained lock (parallel tread): " + lock);

                    lock.release();
                }
                catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();

        JOptionPane.showMessageDialog(null, "Press OK to release lock.");

        lock.release();

        thread.join();
    }

    /**
     * @throws Exception If failed.
     */
    public void testReadLocks() throws Exception {
        final File file = new File(LOCK_FILE_PATH);

        file.createNewFile();

        RandomAccessFile raf = new RandomAccessFile(file, "r");

        System.out.println("Getting lock...");

        FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true);

        System.out.println("Obtained lock: " + lock);

        Thread thread = new Thread(new Runnable() {
            @Override public void run() {
                try {
                    RandomAccessFile raf = new RandomAccessFile(file, "r");

                    System.out.println("Getting lock (parallel thread)...");

                    FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true);

                    System.out.println("Obtained lock (parallel thread): " + lock);

                    lock.release();

                }
                catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start();

        JOptionPane.showMessageDialog(null, "Press OK to release lock.");

        lock.release();

        thread.join();
    }
}

推荐答案

来自 Javadoc:

From the Javadoc:

文件锁是代表整个Java虚拟机.他们是不适合控制访问由多个线程内的一个文件同一个虚拟机.

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.

这篇关于在单个 JVM 内和跨多个 JVM 使用 java 文件锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆