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费心给我找资料,但是我想以我的智商可能还是没有办法把自己的问题说清楚,所以劳您费心了,多谢您给我做了一次初级程序员的扫盲活动。
此帖我找不到如何物理删除的的方法,就发此帖,权当标记删除。来到贵地多谢诸位照顾,不过还是走了,=俺补完程序员初级课程再来请教^_^ |