RAMDirectory类是与内存目录相关的,它和FSDirectory有很大地不同,这主要从它的构造函数来看: public RAMDirectory() { 初始化的时候,指定的是LockFactory抽象类的一个具体实现类SingleInstanceLockFactory。SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例。 实际上,在获取到一个SingleInstanceLockFactory的实例后,那么对该目录Directory进行的所有的锁都已经获取到,这些锁都被存放到SingleInstanceLockFactory类定义的locks中。 因此,多个线程要进行加锁操作的时候,需要考虑同步问题。这主要是在获取SingleInstanceLockFactory中的SingleInstanceLock的时候,同步多个线程,包括请求加锁、释放锁,以及与此相关的共享变量。而SingleInstanceLockFactory类的定义也充分体现了这一点: package org.apache.lucene.store; import java.io.IOException; public class SingleInstanceLockFactory extends LockFactory { private HashSet locks = new HashSet(); public Lock makeLock(String lockName) { public void clearLock(String lockName) throws IOException { class SingleInstanceLock extends Lock { String lockName; public SingleInstanceLock(HashSet locks, String lockName) { public boolean obtain() throws IOException { public void release() { public boolean isLocked() { public String toString() { 因为RAMDirectory是与内存相关的目录,所以它不是永久存在的,不像FSDirectory,所以实例化一个RAMDirectory可以从一个FSDirectory的实例来完成。如下: public RAMDirectory(File dir) throws IOException { public RAMDirectory(String dir) throws IOException { RAMDirectory的这两个构造方法,就是根据一个FSDirectory进行初始化的,即在打开一个FSDirectory的时候,同时就有一个RAMDirectory被创建了。 为什么不直接操作FSDirectory呢?可以想到,执行I/O操作速度很慢的,而在内存中的RAMDirectory处理的效率会有很大的提高。 RAMDirectory的特点决定了,对目录Directory进行复杂的操作时,都要把这些操作转移到内存中来处理。通过拷贝目录的方式也可以实例化一个RAMdirectory,如下所示: public RAMDirectory(Directory dir) throws IOException { 将指定的dir目录拷贝到当前的内存中,即实例化一个RAMDirectory。这里,closeDir是一个很重要的状态变量,指定了拷贝完成后,源目录dir是否关闭。如果实例化一个RAMDirectory完成后就关闭源目录dir,可能会因为处理的时间非常短,而需要再次打开源目录dir,持久化到文件系统目录,开销可能会比直接操作源目录dir要大,这点要权衡。 另外,RAMDirectory类定义的成员中,有一个HashMap成员: HashMap fileMap = new HashMap(); fileMap中存放了从源目录中取得的File,所以在RAMDirectory维护目录中文件的时候,都需要用到fileMap。 而且,管理RAMDirectory的时候,都需要synchronized。 |