zoukankan      html  css  js  c++  java
  • 队列的运用(实例代码)

        /// <summary>
        /// 索引的创建与更新
        /// </summary>
        public class IndexManager
        {
            public static readonly IndexManager Instance = new IndexManager();
            private static readonly string IndexPath = HostingEnvironment.MapPath("~/Index");
            private static ILog log = LogManager.GetLogger(typeof(IndexManager));
    
            private IndexManager()
            { }
    
            //C#的语法中静态构造函数能够确保只调用一次,而且C#是在调用静态构造函数时初始化静态变量,所以通过静态构造函数方法可以保证实例的唯一
            static IndexManager()
            { }
    
            public void Start()
            {
                Thread thread = new Thread(WatchIndexTask);
                thread.IsBackground = true;
                thread.Start();
                log.Debug("IndexManager has been lunched successfully!");
            }
    
            private Queue<IndexTask> indexQueue = new Queue<IndexTask>();       //Queue:表示对象的先进先出集合——队列
            private void WatchIndexTask()
            {
                while (true)
                {
                    if (indexQueue.Count > 0)
                    {
                        // 索引文档保存位置
                        FSDirectory directory = FSDirectory.Open(new DirectoryInfo(IndexPath), new NativeFSLockFactory());
                        bool isUpdate = IndexReader.IndexExists(directory); //判断索引库是否存在
                        log.Debug(string.Format("The status of index : {0}", isUpdate));
                        if (isUpdate)
                        {
                            //  如果索引目录被锁定(比如索引过程中程序异常退出),则首先解锁
                            //  Lucene.Net在写索引库之前会自动加锁,在close的时候会自动解锁
                            //  不能多线程执行,只能处理意外被永远锁定的情况
                            if (IndexWriter.IsLocked(directory))
                            {
                                log.Debug("The index is existed, need to unlock.");
                                IndexWriter.Unlock(directory);  //unlock:强制解锁,待优化
                            }
                        }
                        //  创建向索引库写操作对象  IndexWriter(索引目录,指定使用盘古分词进行切词,最大写入长度限制)
                        //  补充:使用IndexWriter打开directory时会自动对索引库文件上锁
                        IndexWriter writer = new IndexWriter(directory, new PanGuAnalyzer(), !isUpdate,
                            IndexWriter.MaxFieldLength.UNLIMITED);
                        log.Debug(string.Format("Total number of task : {0}", indexQueue.Count));
    
                        while (indexQueue.Count > 0)
                        {
                            IndexTask task = indexQueue.Dequeue();
                            long id = task.TaskId;
                            ArticleService articleService = new ArticleService();
                            Article article = articleService.GetById(id);
    
                            if (article == null)
                            {
                                continue;
                            }
    
                            //  一条Document相当于一条记录
                            Document document = new Document();
                            //  每个Document可以有自己的属性(字段),所有字段名都是自定义的,值都是string类型
                            //  Field.Store.YES不仅要对文章进行分词记录,也要保存原文,就不用去数据库里查一次了
                            document.Add(new Field("id", id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                            //  需要进行全文检索的字段加 Field.Index. ANALYZED
                            //  Field.Index.ANALYZED:指定文章内容按照分词后结果保存,否则无法实现后续的模糊查询 
                            //  WITH_POSITIONS_OFFSETS:指示不仅保存分割后的词,还保存词之间的距离
                            document.Add(new Field("title", article.Title, Field.Store.YES, Field.Index.ANALYZED,
                                Field.TermVector.WITH_POSITIONS_OFFSETS));
                            document.Add(new Field("msg", article.Msg, Field.Store.YES, Field.Index.ANALYZED,
                                Field.TermVector.WITH_POSITIONS_OFFSETS));
                            if (task.TaskType != TaskTypeEnum.Add)
                            {
                                //  防止重复索引,如果不存在则删除0条
                                writer.DeleteDocuments(new Term("id", id.ToString()));// 防止已存在的数据 => delete from t where id=i
                            }
    
                            //  把文档写入索引库
                            writer.AddDocument(document);
    
                            log.Debug(string.Format("Index {0} has been writen to index library!", id.ToString()));
                        }
    
                        writer.Close(); // Close后自动对索引库文件解锁
                        directory.Close();  //  不要忘了Close,否则索引结果搜不到
    
                        log.Debug("The index library has been closed!");
                    }
                    else
                    {
                        Thread.Sleep(2000);
                    }
                }
            }
    
            public void AddArticle(IndexTask task)
            {
                task.TaskType = TaskTypeEnum.Add;
                indexQueue.Enqueue(task);
            }
    
            public void UpdateArticle(IndexTask task)
            {
                task.TaskType = TaskTypeEnum.Update;
                indexQueue.Enqueue(task);
            }
        }
    
        public class IndexTask
        {
            public long TaskId { get; set; }
    
            public TaskTypeEnum TaskType { get; set; }
        }
    
        public enum TaskTypeEnum
        {
            Add,
            Update
        }
  • 相关阅读:
    解决Error:com.intellij.util.indexing.StorageException
    Spring AOP (上)
    spring aop expression简单说明
    Spring AOP 详解
    基于Spring AOP实现对外接口的耗时监控
    JavaEE参考示例 SpringSide 4.0 GA版杀青
    MyBatis学习 之 四、MyBatis配置文件
    MyBatis学习 之 三、动态SQL语句
    MyBatis学习 之 二、SQL语句映射文件(2)增删改查、参数、缓存
    MyBatis学习 之 二、SQL语句映射文件(1)resultMap
  • 原文地址:https://www.cnblogs.com/zhangchaoran/p/7659645.html
Copyright © 2011-2022 走看看