首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:线程安全RandomAccessFile

Java:线程安全RandomAccessFile
EN

Stack Overflow用户
提问于 2010-05-21 20:52:56
回答 5查看 11.8K关注 0票数 12

经过认真的谷歌搜索,我发现RandomAccessFile-class不是线程安全的。现在我可以使用一个信号量来锁定所有的读写操作,但我不认为这样做效果很好。从理论上讲,应该可以一次进行多次读取和一次写入。我如何在Java中做到这一点?这是完全可能的吗?

谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-05-21 21:12:51

文件的部分锁定是一项复杂的业务,许多操作系统都会避免这样做。但是,如果您坚持这样做,一种方法是设计您自己的锁定机制对象,该对象记录文件的哪些部分被锁定。本质上,在读取或写入之前,对象必须请求文件的特定字节范围的锁。如果锁在字节范围内完全重叠,则认为它们发生了冲突。读锁和写锁的处理方式不同:一个读锁可以安全地与任意数量的读锁重叠,但一个写锁必须与其他锁(读或写)重叠。如果不能获得锁,是否等待或中止,以及是否在写入等待时阻止读取,有很多问题,但只有您可以回答关于您的应用程序的问题。

考虑到这一点的复杂性,锁定整个文件可能更好。检查您是否获得了足够的性能-不要忘记,只要没有写入,您就可以一次允许多次读取。

票数 3
EN

Stack Overflow用户

发布于 2010-05-21 21:00:48

,我可以使用一个信号量来锁定所有的读写操作,但我不认为这样做效果很好。

关于性能,永远不要去想。永远都要衡量。

也就是说,java.util.concurrent.locks.ReentrantReadWriteLock就是你要找的东西。

票数 7
EN

Stack Overflow用户

发布于 2010-05-21 21:14:30

考虑这种方法-它允许无限的读取器,并且当写入器想要写入时,它等待当前读取器完成其写入。

代码语言:javascript
复制
class readWriteSemaphore() {
    private Object lock;
    List<Thread> readers;
    Thread writer;

    readWriteSemaphore() {
        readers = new LinkedList<Thread>(); // Linked list is inefficient for many threads, FYI
        writer = null;
    }

    /**
    * Returns true if and only if you have acquired a read
    * maybe use while(!rws.acquireRead(Thread.currentThread())) Thread.sleep(50); // or something
    */
    boolean acquireRead(Thread t) {
        synchronized(lock) {
            if(writer == null) {
                readers.add(t);
                return true;
            }
            return false; // yes this could go outside the synch block... oh well
        }
    }

    void releaseRead(Thread t) {
        synchronized(lock) {
            while(readers.remove(t)); // remove this thread completely
        }
    }

    boolean acquireWrite(Thread t) {
        synchronized(lock) {
            if(writer == null) return false;
            writer = t;
        }
        while(readers.size() > 0) Thread.sleep(50); // give readers time to finish. 
        //They can't re-enter yet because we set the writer,
        // if you attempt to acquire a write, future reads will be false until you're done
        return true;
    }

    void releaseWrite(Thread t) {
        synchronized(lock) {
            if(t != writer) throw new IllegalArgumentException("Only writer can release itself");
            writer = null;
        }
    }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2882168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档