原因 :

         IndexWriter在初始化索引的时候会为这个索引加锁,等到初始化完成之后,调用其close()方法关闭IndexWriter,在close()这个方法的内部其实也是调用了unlock()来释放锁,当程序结束后IndexWriter没有正常关闭的时候,再次创建索引就会报

org.apache.lucene.store.LockObtainFailedException:Lock obtain timed out :

NativeFsLock@ XXXX\write.lock

           这个异常是因为lucene进入到索引目录中,发现里面就是一个write.lock。而IndexWriter的构造函数在试图获取另外一个IndexWriter已经加锁的索引目录时就会抛出一个LockObtainFailedException。

解决方法:

        把当前索引目录下的 write.lock 删掉,重新创建索引

        每次使用索引后,要及时的释放掉

indexWriter.close();

        个人在使用过程中,即使每次使用完都释放掉资源还是会报错

/**
 * 抽出公用创建索引方法
 * @param indexPath
 * @return 索引
 * @throws IOException
 */
public static IndexWriter getIndexWriter(String indexPath) throws IOException {
    File file = new File(indexPath );
    if (!file.exists()) {
        file.mkdirs();
    }
    // 索引目录类,指定索引在硬盘中的位置
    Directory directory = FSDirectory.open(file);
    // 创建分词器对象
    Analyzer analyzer = new IKAnalyzer();
    //StandardAnalyzer analyzer=new StandardAnalyzer();
    // 索引写出工具的配置对象
    IndexWriterConfig conf = new IndexWriterConfig(Version.LATEST, analyzer);
    conf.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
    // 创建索引的写入工具类。参数:索引的目录和配置信息
    IndexWriter indexWriter = new IndexWriter(directory, conf);
    return indexWriter;
}
@Test
public  void fgxxCreate() throws IOException {
    // 创建文档的集合
    Collection<Document> docs = new ArrayList<>();
    //创建文档对象
    Document document1 = new Document();
    document1.add(new StringField("id", "文档IDA02", Field.Store.YES));
    document1.add(new TextField("fgname","中华人民共和国刑法", Field.Store.YES));
    docs.add(document1);

    Document document2 = new Document();
    document2.add(new StringField("id", "文档IDA02", Field.Store.YES));
    document2.add(new TextField("fgname","中华人民共和国民事诉讼法", Field.Store.YES));
    docs.add(document2);

    Document document3 = new Document();
    document3.add(new StringField("id", "文档IDA04", Field.Store.YES));
    document3.add(new TextField("fgname","中华人民共和国行政诉讼法", Field.Store.YES));
    docs.add(document3);

    Document document4 = new Document();
    document4.add(new StringField("id", "文档IDA05", Field.Store.YES));
    document4.add(new TextField("fgname","中华人民共和国劳动法", Field.Store.YES));
    docs.add(document4);

    //根据附件读取文本内容
   // String fileText = getFileText(filepath);
    //document.add(new TextField("fjtext", fileText, Field.Store.YES));
    //创建索引
    IndexWriter indexWriter = getIndexWriter("E:\\Luceneindex");
    //把文档交给IndexWriter
    indexWriter.addDocuments(docs);
    //提交
    indexWriter.commit();
    // 关闭
    indexWriter.close();
}

经过排查,怀疑是操作过于频繁,以及将异常抛出导致、没有及时的释放资源导致的。

有大佬知道具体原因望告知。

后续将异常捕获处理,再次测试,没有出现当前报错。

IndexWriter indexWriter = null;
try {
    indexWriter = getIndexWriter("E:\\Luceneindex");

    //把文档交给IndexWriter
    indexWriter.addDocuments(docs);
    //提交
    indexWriter.commit();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (indexWriter != null) {
            // 关闭
            indexWriter.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐