zoukankan      html  css  js  c++  java
  • 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;
     
    

      

     

  • 相关阅读:
    android开发之重写Application类
    android开发之Parcelable使用详解
    android开发之Bundle使用
    android开发之gridlayout使用入门
    android开发之merge结合include优化布局
    android开发布局优化之ViewStub
    android开发之PreferenceScreen使用详解
    android开发之使用Messenger实现service与activity交互
    LeetCode All in One 题目讲解汇总(持续更新中...)
    JavaWeb知识点总结
  • 原文地址:https://www.cnblogs.com/huangfox/p/3124211.html
Copyright © 2011-2022 走看看