经过认真的谷歌搜索,我发现RandomAccessFile-class不是线程安全的。现在我可以使用一个信号量来锁定所有的读写操作,但我不认为这样做效果很好。从理论上讲,应该可以一次进行多次读取和一次写入。我如何在Java中做到这一点?这是完全可能的吗?
谢谢!
发布于 2010-05-21 21:12:51
文件的部分锁定是一项复杂的业务,许多操作系统都会避免这样做。但是,如果您坚持这样做,一种方法是设计您自己的锁定机制对象,该对象记录文件的哪些部分被锁定。本质上,在读取或写入之前,对象必须请求文件的特定字节范围的锁。如果锁在字节范围内完全重叠,则认为它们发生了冲突。读锁和写锁的处理方式不同:一个读锁可以安全地与任意数量的读锁重叠,但一个写锁必须与其他锁(读或写)重叠。如果不能获得锁,是否等待或中止,以及是否在写入等待时阻止读取,有很多问题,但只有您可以回答关于您的应用程序的问题。
考虑到这一点的复杂性,锁定整个文件可能更好。检查您是否获得了足够的性能-不要忘记,只要没有写入,您就可以一次允许多次读取。
发布于 2010-05-21 21:00:48
,我可以使用一个信号量来锁定所有的读写操作,但我不认为这样做效果很好。
关于性能,永远不要去想。永远都要衡量。
也就是说,java.util.concurrent.locks.ReentrantReadWriteLock就是你要找的东西。
发布于 2010-05-21 21:14:30
考虑这种方法-它允许无限的读取器,并且当写入器想要写入时,它等待当前读取器完成其写入。
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;
}
}
}https://stackoverflow.com/questions/2882168
复制相似问题