where to close IndexWriter?

littlesuns 2007-11-14
一般的来说,我们会这样创建一个lucene IndexWriter:
try{
    IndexWriter writer = new IndexWriter(...);
    List documents=getLuceneDocuments();
    for(int i = 0; i<documents.size(); i++){
        writer.add(documents.get(i));
    }
    write.close();
} catch (Exception e) {
    throw e;
}

这里有一个问题:我们是否应该把write.close()放置在一个finally block中?像这样:
try{
    IndexWriter writer = new IndexWriter(...);
    List documents=getLuceneDocuments();
    for(int i = 0; i<documents.size(); i++){
        writer.add(documents.get(i));
    }
} catch (Exception e) {
    throw e;
} finally {
    write.close();
}

让我们看看在我们调用IndexWriter.close()的时候他都做了什么:
public synchronized void close() throws CorruptIndexException, IOException {
    if (!closed) {
      flushRamSegments();

      if (commitPending) {
        segmentInfos.write(directory);         // now commit changes
        deleter.checkpoint(segmentInfos, true);
        commitPending = false;
        rollbackSegmentInfos = null;
      }

      ramDirectory.close();
      if (writeLock != null) {
        writeLock.release();                          // release write lock
        writeLock = null;
      }
      closed = true;

      if(closeDir)
        directory.close();
    }
  }

这里有两个很重要的statement:
    flushRamSegments();


    ramDirectory.close();

如我们所知,我们在向IndexWriter中添加Document的时候,并不会马上把索引写入硬盘上的对应文件,这一切都是在内存中进行的,当我们close已经添加完document的writer时,flushRamSegments(),将内存中的变更同步到硬盘上,之后ramDirectory.close(),释放内存,实际上是做了一个赋空值的动作,让内存等待GC回收(可以去看源码),如果说这是一个资源释放的话,我们应该是将close放在finally块中的,但是,如果我们在writer.close()之前,例如添加document的时候出错了,此时内存中的Index应该不是我们需要的Index,由于finally块的存在,我们要去flush内存中已经错误的Index,恐怕这也不是我们想要看到的,那么,close究竟应该放在哪个位置?what do you think?
imjl 2007-11-14
请尽量用文字来表述,还没有无法用文字表述的问题。

littlesuns 2007-11-14
汗。。。我又不是全System.out.print()出来的,人比较Ben,麻烦详细说下如何"文字表述"
imjl 2007-11-15
littlesuns 写道
汗。。。我又不是全System.out.print()出来的,人比较Ben,麻烦详细说下如何"文字表述"


不用代码说问题。
littlesuns 2007-11-16
o,那我就一句话说明:IndexWriter究竟要不要放在finally块里,另外:to imjl
什么情况下才能用代码说问题?
imjl 2007-11-18
littlesuns 写道
o,那我就一句话说明:IndexWriter究竟要不要放在finally块里,另外:to imjl
什么情况下才能用代码说问题?


前者属于code范围,你可以看下finally的说明。这里只讨论和lucene有关的话题。

当你不在这里发问的时候也许可以把。


littlesuns 2007-11-19
这怎么属于finally的问题,我的意思是IndexWriter究竟是否适合在finally的块中调用close方法,如果imjl还是觉得不是Lucene的问题,请告知我,此帖我会删掉。
imjl 2007-11-19
这是从http://www.itsway.net/java/java060301.aspx  复制过来的
引用

  try {Java程序块;} catch(异常类名 形式参数名){异常处理语句块; } catch(异常类名 形式参数名){异常处理语句块; }   …… finally {语句块;}

其中try语句块存放将可能发生异常的Java程序;catch语句块紧跟在try块后面,用来捕获被激发的异常。catch语句块可能不只一个,每一个catch语句块处理一种可能出现的异常; finally遇见块是可选的,经常不写,它一般包含清除程序没有释放的资源等代码。如果有finally块,则发生异常时,无论try块中的代码如何退出,都将执行finally块。


正常走,那么就是从实例化到close。 因为考虑到其间有可能出现异常,所以采用try catch,,如上所述
finally无论上面怎么变化都会走到。

从你贴的code来看,第一个就可以了。

如何释放资源,是否释放?我觉得java会自己处理了。你从c过来的吗?(我猜想一旦出错,它就把之前调用的信息做个标记,如果程序结束就释放)

我不会java。这个问题你要问的应该是try catch中资源如何释放。



littlesuns 2007-11-20
多谢imjl费心给我找资料,但是我想以我的智商可能还是没有办法把自己的问题说清楚,所以劳您费心了,多谢您给我做了一次初级程序员的扫盲活动。

此帖我找不到如何物理删除的的方法,就发此帖,权当标记删除。来到贵地多谢诸位照顾,不过还是走了,=俺补完程序员初级课程再来请教^_^
Global site tag (gtag.js) - Google Analytics