lucene referenceManager

问题的引入:

Hello, I am using the reopen method in the IndexReader class. In the case 
of the IndexReader being updated, I would like to create a new IndexSearcher 
and close the old IndexReader. When closing an instance of IndexReader, do I 
have to wait for currently executing searches (through an IndexSearcher with 
this instance of the IndexReader) to complete? The javadoc states that I 
should not invoke any method on the reader after the close is called, but I 
am curious about the state of the searches that are using the reader when 
the close is called. 
I would appreciate any thoughts on the question and on my approach. 
Thanks!

http://www.gossamer-threads.com/lists/lucene/java-user/66339

对于一个资源,如果我们要关闭(或者重新打开)得确保他没有被“引用”,否则硬生生的关闭将导致当前引用他的任务执行失败。

因此我们需要对这个资源进行引用计数,引用一次refValue加1,执行完毕refValue减1,关闭资源时需要确保refValue等于0。

ReferenceManager就实现了这个功能。

Utility class to safely share instances of a certain type across multiple threads, while periodically refreshing them. This class ensures each reference is closed only once all threads have finished using it. It is recommended to consult the documentation of ReferenceManager implementations for their maybeRefresh() semantics.

引用、归还资源

acquire() 
          Obtain the current reference.

release(G reference) 
          Release the refernce previously obtained via acquire().

  public final G acquire() {
    G ref;
    do {
      if ((ref = current) == null) {
        throw new AlreadyClosedException(REFERENCE_MANAGER_IS_CLOSED_MSG);
      }
    } while (!tryIncRef(ref));
    return ref;
  }

  public final void release(G reference) throws IOException {
    assert reference != null;
    decRef(reference);
  }

tryIncRef(ref)和decRef(reference)需要在子类中实现。

例如SearchManager中tryIncRef、decRed的实现如下:

searchManager执行indexReader中的tryIncRef、decRed方法。

public final boolean tryIncRef() {
    int count;
    while ((count = refCount.get()) > 0) {
      if (refCount.compareAndSet(count, count+1)) {
        return true;
      }
    }
    return false;
  }


public final void decRef() throws IOException {
    ensureOpen();
    final int rc = refCount.decrementAndGet();
    if (rc == 0) {
      boolean success = false;
      try {
        commit();
        doClose();
        success = true;
      } finally {
        if (!success) {
          // Put reference back on failure
          refCount.incrementAndGet();
        }
      }
      notifyReaderClosedListeners();
    } else if (rc < 0) {
      throw new IllegalStateException("too many decRef calls: refCount is " + rc + " after decrement");
    }
  }

  

 

SearchManager的应用方式:

IndexSearcher s = manager.acquire();
 try {
   // Do searching, doc retrieval, etc. with s
 } finally {
   manager.release(s);
 }
 // Do not use s after this!
 s = null;
 

  

 

原文地址:https://www.cnblogs.com/huangfox/p/3124211.html