RAMDirectory类是与内存目录相关的,它和FSDirectory有很大地不同,这主要从它的构造函数来看:
public RAMDirectory() {
setLockFactory(new SingleInstanceLockFactory());
}
初始化的时候,指定的是LockFactory抽象类的一个具体实现类SingleInstanceLockFactory。SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例。
实际上,在获取到一个SingleInstanceLockFactory的实例后,那么对该目录Directory进行的所有的锁都已经获取到,这些锁都被存放到SingleInstanceLockFactory类定义的locks中。
因此,多个线程要进行加锁操作的时候,需要考虑同步问题。这主要是在获取SingleInstanceLockFactory中的SingleInstanceLock的时候,同步多个线程,包括请求加锁、释放锁,以及与此相关的共享变量。而SingleInstanceLockFactory类的定义也充分体现了这一点:
package org.apache.lucene.store;
import java.io.IOException;
import java.util.HashSet;
import java.util.Enumeration;
public class SingleInstanceLockFactory extends LockFactory {
private HashSet locks = new HashSet();
public Lock makeLock(String lockName) {
//从锁工厂中, 根据指定的锁lockName返回一个SingleInstanceLock实例
return new SingleInstanceLock(locks, lockName);
}
public void clearLock(String lockName) throws IOException {
synchronized(locks) { // 从SingleInstanceLockFactory中清除某个锁的时候,需要同步
if (locks.contains(lockName)) {
locks.remove(lockName);
}
}
}
};
class SingleInstanceLock extends Lock {
String lockName;
private HashSet locks;
public SingleInstanceLock(HashSet locks, String lockName) {
this.locks = locks;
this.lockName = lockName;
}
public boolean obtain() throws IOException {
synchronized(locks) { // 获取锁时需要同步
return locks.add(lockName);
}
}
public void release() {
synchronized(locks) { // 释放锁时需要同步
locks.remove(lockName);
}
}
public boolean isLocked() {
synchronized(locks) {
return locks.contains(lockName);
}
}
public String toString() {
return "SingleInstanceLock: " + lockName;
}
}
因为RAMDirectory是与内存相关的目录,所以它不是永久存在的,不像FSDirectory,所以实例化一个RAMDirectory可以从一个FSDirectory的实例来完成。如下:
public RAMDirectory(File dir) throws IOException {
this(FSDirectory.getDirectory(dir), true);
}
public RAMDirectory(String dir) throws IOException {
this(FSDirectory.getDirectory(dir), true);
}
RAMDirectory的这两个构造方法,就是根据一个FSDirectory进行初始化的,即在打开一个FSDirectory的时候,同时就有一个RAMDirectory被创建了。
为什么不直接操作FSDirectory呢?可以想到,执行I/O操作速度很慢的,而在内存中的RAMDirectory处理的效率会有很大的提高。
RAMDirectory的特点决定了,对目录Directory进行复杂的操作时,都要把这些操作转移到内存中来处理。通过拷贝目录的方式也可以实例化一个RAMdirectory,如下所示:
public RAMDirectory(Directory dir) throws IOException {
this(dir, false);
}
private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
this();
Directory.copy(dir, this, closeDir);
}
将指定的dir目录拷贝到当前的内存中,即实例化一个RAMDirectory。这里,closeDir是一个很重要的状态变量,指定了拷贝完成后,源目录dir是否关闭。如果实例化一个RAMDirectory完成后就关闭源目录dir,可能会因为处理的时间非常短,而需要再次打开源目录dir,持久化到文件系统目录,开销可能会比直接操作源目录dir要大,这点要权衡。
另外,RAMDirectory类定义的成员中,有一个HashMap成员:
HashMap fileMap = new HashMap();
fileMap中存放了从源目录中取得的File,所以在RAMDirectory维护目录中文件的时候,都需要用到fileMap。
而且,管理RAMDirectory的时候,都需要synchronized。
转自:http://www.cnblogs.com/lvpei/articles/1731817.html
相关推荐
在 C# 中,建议不要定义类的析构函数,因为 C# 中无用的对象会由垃圾回收器回收,如果构造函数中执行较为耗时的操作会影响垃圾收集器的功能。 自定义类的制作是 C# 编程中的一项重要技术,它可以帮助开发者提高编程...
本次任务是一个较为复杂的新闻文本分类的任务,首先需要使用bert模型对新闻文本进行分类,然后使用Django构建一个文本分类结果查询的可视化系统。 我们的任务是要构建一个模型,任意输入一篇新闻文章,可以将新闻...
针对附件上传文件名包含特殊字符的问题,可以通过限制用户上传这类文件来简化处理流程,但这样可能会降低用户体验。另一种更为全面的方法是通过对文件名进行编码和解码来确保文件能够正常上传和下载。虽然这种方法...
在编程世界里,虽然大多数情况下我们使用的都是常见的字母、数字以及一些基本的操作符(如加号“+”、减号“-”等),但有时也会遇到一些较为特殊的符号。这些符号可能不会在日常编程中频繁出现,但在某些特定场合下...
使用自编《特殊群体筛查问卷》从大学生中筛选出特殊群体,运用针对不同特殊群体的不同辅导方案,培养他们较为缺乏的人格品质。SCL-90前后测T检验发现,学习问题群体除了冲动因子其它因子分均比原来显著下降;经济困难...
通过描述部分:“特殊符号大全,一些罕有的符号也有额,聊天的时候打出来,别人没有的”可以进一步了解,这份资料不仅仅包含常见的特殊符号,还包含了一些较为罕见的符号,非常适合用于个性化聊天或创作时使用。...
这些模板通常风格较为正式,色彩和图形元素相对保守,以确保学术性和专业性。 总的来说,这个压缩包提供的模板覆盖了多个行业,具有很高的实用价值。用户可以根据自己的需求选择合适的模板,快速搭建起符合场景的...
较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的家装CAD图库较为齐全的...
### 支持向量机多类分类方法 #### 引言 支持向量机(Support Vector Machine, SVM)作为一种强大的机器学习模型,在处理二分类问题时展现出了卓越的能力。然而,许多实际应用场景需要解决的是多类分类问题。因此,...
* 抽象类是Java语言中的一种特殊类,用abstract关键字来修饰一个类时,这个类叫做抽象类。 * 抽象类必须被继承,抽象方法必须被重写。 * 抽象方法只需声明,无需实现;抽象类不能被实例化,抽象类不一定要包含抽象...
String类是C#中的基本类型,但它的操作往往较为复杂。String Helper类可以提供一些实用的方法,如字符串格式化、去除空格、检查是否包含子串、替换特定字符等,以简化字符串处理。 2. **FTP Helper**: FTP ...
基于目前科技发展水平和自然资源的差异,世界上许多产煤大国均有其煤炭分类标准,因而从标准类型、煤类术语和指标选择、指标定义等方面对国际上较为常见的标准进行了归类和对比。对比分析后发现:西方国家的分类标准在...
在VB中,直接使用Winsock API可能会较为复杂,因此通常会将其封装成一个类,简化调用过程。 这个名为"一个Socket连接类,封装了Winsock API"的VB类,可能包含以下核心功能: 1. 初始化与配置:类的初始化通常涉及...
Java Bean是一种特殊类型的Java类,遵循特定的命名规则和方法签名,使得这些类易于被其他Java应用或框架使用,例如Spring框架。 实体类通常包含以下几部分: 1. **属性(Fields)**:对应数据库表的列,用private...
在中国的法律环境中,对一般债权质押的规定较为模糊,学术界对此有两种观点,一种认为未在担保法中明确规定则不可质押,另一种认为可视为"依法可以质押的其他权利"。为了保障交易安全和效率,明确各方的权利义务对于...
- 匿名内部类是在创建对象时没有明确给出类名的一种特殊类形式。 - 它通常用于创建接口或者抽象类的一个实例,而这个实例仅在当前作用域内使用。 - 匿名内部类可以访问外部类的所有成员变量和方法,包括私有成员...
电子支付的分类和定义 电子支付是一种基于计算机网络的支付...电子支付的运作环境一般是一个开放的计算机网络系统,而传统商务一般都是在一个较为封闭的系统中进行;在线电子支付快捷、高效、低成本;安全风险突出。
抽象类是一种特殊的类,它不能被实例化,但可以作为其他类的基类。抽象类的主要目的是为了提供一种模板设计,它定义了一组可能的方法,但不提供具体的实现。当一个类包含至少一个抽象方法时,该类就必须被声明为抽象...