lucene2.4源码学习2 写文件之WaitQueue
lucene是多线程写文件的,但是也要写出来的文件号是从小到大的。也就是最后写的时候还需要一个同步的过程。
当文档号低的还没有生成完,但是另外一个线程的已经生成好一个文档号高的文档了,这个时候怎么办,这个时候文档号高的是不能写的,要等到文档号低的写完再写。
lucene的做法是把这些高的文档加入到一个队列,即WaitQueue。
这样当低文档写完的时候,还会去写准备好的高的文档。注意有个while循环,而writeDocument方法有个nextWriteLoc++会不断往前
synchronized public boolean add(DocWriter doc) throws IOException { assert doc.docID >= nextWriteDocID; if (doc.docID == nextWriteDocID) { writeDocument(doc); while(true) { doc = waiting[nextWriteLoc]; if (doc != null) { numWaiting--; waiting[nextWriteLoc] = null; waitingBytes -= doc.sizeInBytes(); [color=red] writeDocument(doc);[/color] } else break; }
private void writeDocument(DocWriter doc) throws IOException { assert doc == skipDocWriter || nextWriteDocID == doc.docID; boolean success = false; try { doc.finish(); nextWriteDocID++; numDocsInStore++;nextWriteLoc++;
assert nextWriteLoc <= waiting.length;
if (nextWriteLoc == waiting.length)
nextWriteLoc = 0;
success = true;
} finally {
if (!success)
setAborting();
}
}
synchronized boolean doPause() { return waitingBytes > waitQueuePauseBytes; }
private long ramBufferSize = (long) (IndexWriter.DEFAULT_RAM_BUFFER_SIZE_MB*1024*1024); private long waitQueuePauseBytes = (long) (ramBufferSize*0.1);
if (doPause) waitForWaitQueue();
synchronized void waitForWaitQueue() { do { try { wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } while (!waitQueue.doResume()); }
synchronized boolean doResume() { return waitingBytes <= waitQueueResumeBytes; }