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;
     
    

      

     

  • 相关阅读:
    form表单回车提交
    Mac os x下配置nginx + php
    Mac下git命令自动补全
    关于javascript中的操作符&&和||的最终返回值
    ARM 裸机程序学习 01 点亮LED
    LINUX SHELL 中 2>&1 重定向的问题
    项目经理到底关心项目的什么?——有关外包项目成本的计算
    ARM 裸机程序学习 03 发送SOS信号(汇编 + C)
    ARM 裸机程序学习 02 按响BEEP
    备忘录 Linux及其内核杂项知识
  • 原文地址:https://www.cnblogs.com/huangfox/p/3124211.html
Copyright © 2011-2022 走看看