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;
     
    

      

     

  • 相关阅读:
    golang动态加载原生代码思路
    boltdb的实现和改进
    如何保证数据掉电不损坏?
    msgpack库的神奇用法
    消息推送与同步协议的思考
    cassandra的gc调优
    tcp链接断开的探测
    加速和监控国际网络
    轻松逃脱某防火墙对ss的探测
    java文件操作之war压缩解压
  • 原文地址:https://www.cnblogs.com/huangfox/p/3124211.html
Copyright © 2011-2022 走看看