• 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;
     
    

      

     

  • 相关阅读:
    剑指Offer_编程题_包含min函数的栈
    剑指Offer_编程题_顺时针打印矩阵
    Docker基础(3) 数据卷
    Docker基础(2) 实践篇
    Docker基础(1) 原理篇
    《算法》笔记 17
    《算法》笔记 16
    《算法》笔记 15
    《算法》笔记 14
    《算法》笔记 13
  • 原文地址:https://www.cnblogs.com/huangfox/p/3124211.html
Copyright © 2020-2023  润新知