zoukankan      html  css  js  c++  java
  • Lucene.Net 多线程操作建议(转)

    对于并发,Lucene.Net 遵循以下规则:

    1. 允许任意多的读操作并发,即任意数量用户可同时对同一索引做检索操作。
    2. 即便正在进行索引修改操作(索引优化、添加文档、删除文档),依然允许任意多的检索操作并发执行。
    3. 不允许并发修改操作,也就是说同一时间只允许一个索引修改操作。

    Lucene.Net 内部已经对多线程安全进行了处理,打开 IndexWrite.cs / IndexReade.csr 文件,会发现很多操作都使用了 lock 进行多线程同步锁定。只要遵循一定的规则,就可以在多线程环境下安全运行 Lucene.Net。

    建议:

    1. Directotry、Analyzer 都是多线程安全类型,只需建立一个 Singleton 对象即可。
    2. 所有线程使用同一个 IndexModifier 对象进行索引修改操作。
    3. IndexWriter/IndexReader/IndexModifier/IndexSearcher 最好使用同一个 Directory 对象,否则多线程并发读写时可能引发 FileNotFoundException。

    IndexModifier 对象封装了 IndexWriter 和 IndexReader 的常用操作,其内部实现了多线程同步锁定。使用 IndexModifier 可避免同时使用 IndexWriter 和 IndexReader 时需要在多个对象之间进行同步的麻烦。等所有修改操作完成后,记住调用 Close() 方法关闭相关资源。并不是每次操作都需要调用 Optimize(),可以依据特定情况,定期执行优化操作。

    --------

    以下演示代码简单封装了一个 IndexModifier Signleton 类型,确保多线程使用同一个对象,且只能由最后一个多线程调用 Close 方法关闭。
    代码不完善,仅供参考!需要做些修改才能应用于实际项目。

    public class MyIndexModifier
    {
      private static Directory directory = new RAMDirectory();
      private static Analyzer analyzer = new StandardAnalyzer();
      private static IndexModifier modifier;
      private static List<Thread> threadList = new List<Thread>();
      
      private MyIndexModifier() { }

      public static IndexModifier GetInstance()
      {
        lock (threadList)
        {
          if (modifier == null)
          {
            modifier = new IndexModifier(directory, analyzer, false);
            modifier.SetMaxFieldLength(1000);
          }

          if (!threadList.Contains(Thread.CurrentThread))
            threadList.Add(Thread.CurrentThread);

          return modifier;
        }
      }

      public static void Close()
      {
        lock (threadList)
        {
          if (threadList.Contains(Thread.CurrentThread))
            threadList.Remove(Thread.CurrentThread);

          if (threadList.Count == 0)
          {
            if (modifier != null)
            {
              modifier.Close();
              modifier = null;
            }
          }
        }
      }
    }


    多线程测试代码

    for (int i = 0; i < 100; i++)
    {
      new Thread(delegate()
      {
        IndexModifier writer = MyIndexModifier.GetInstance();

        for (int x = 0; x < 10; x++)
        {
          Document doc = new Document();
          doc.Add(Field.Text("a", "Hello, World!"));
          writer.AddDocument(doc);
        }

        Console.WriteLine("{0}: {1}", Thread.CurrentThread.ManagedThreadId, writer.DocCount());
        MyIndexModifier.Close(); // 注意不是调用 IndexModifier.Close() !

      }).Start();
    }
  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/zhwl/p/2359271.html
Copyright © 2011-2022 走看看