我们前天讲到了需要加入多线程来缓解界面卡死的现象,那现在就让我来给大家介绍一个由博客园的某位大牛写的线程池。(实在是忘了是谁了、、)

线程池的代码奉上:

  1     sealed class MyThreadPool
  2     {
  3         //线程锁对象
  4         private static object lockObj = new object();
  5         //任务队列
  6         private static Queue<ThreadStart> threadStartQueue = new Queue<ThreadStart>();
  7         //记录当前工作的任务集合,从中可以判断当前工作线程使用数,如果使用int判断的话可能会有问题,
  8         //用集合的话还能取得对象的引用,比较好
  9         private static HashSet<ThreadStart> threadsWorker = new HashSet<ThreadStart>();
 10         //当前允许最大工作线程数
 11         private static int maxThreadWorkerCount = 1;
 12         //当前允许最小工作线程数
 13         private static int minThreadWorkerCount = 0;
 14 
 15         /// <summary>
 16         /// 设定最大工作线程数
 17         /// </summary>
 18         /// <param name="maxThreadCount">数量</param>
 19         public static void SetMaxWorkThreadCount(int maxThreadCount)
 20         {
 21             maxThreadWorkerCount = minThreadWorkerCount > maxThreadCount ?
 22             minThreadWorkerCount : maxThreadCount;
 23         }
 24         /// <summary>
 25         /// 设定最小工作线程数
 26         /// </summary>
 27         /// <param name="maxThreadCount">数量</param>
 28         public static void SetMinWorkThreadCount(int minThreadCount)
 29         {
 30             minThreadWorkerCount = minThreadCount > maxThreadWorkerCount ?
 31             maxThreadWorkerCount : minThreadCount;
 32         }
 33         /// <summary>
 34         /// 启动线程池工作
 35         /// </summary>
 36         /// <param name="threadStartArray">任务数组</param>
 37         public static void MyQueueUserWorkItem(List<ThreadStart> threadStartArray)
 38         {
 39             //将任务集合都放入到线程池中
 40             AddAllThreadsToPool(threadStartArray);
 41             //线程池执行任务
 42             ExcuteTask();
 43         }
 44         /// <summary>
 45         /// 将单一任务加入队列中
 46         /// </summary>
 47         /// <param name="ts">单一任务对象</param>
 48         private static void AddThreadToQueue(ThreadStart ts)
 49         {
 50             lock (lockObj)
 51             {
 52                 threadStartQueue.Enqueue(ts);
 53             }
 54         }
 55 
 56         /// <summary>
 57         /// 将多个任务加入到线程池的任务队列中
 58         /// </summary>
 59         /// <param name="threadStartArray">多个任务</param>
 60         private static void AddAllThreadsToPool(List<ThreadStart> threadStartArray)
 61         {
 62             foreach (var threadStart in threadStartArray)
 63                 AddThreadToQueue(threadStart);
 64         }
 65 
 66         /// <summary>
 67         /// 执行任务,判断队列中的任务数量是否大于0,如果是则判断当前正在使用的工作线程的
 68         /// 数量是否大于等于允许的最大工作线程数,如果一旦有线程空闲的话
 69         /// 就会执行ExcuteTaskInQueen方法处理任务
 70         /// </summary>
 71         private static void ExcuteTask()
 72         {
 73             while (threadStartQueue.Count > 0)
 74             {
 75                 Thread.Sleep(100);
 76                 if (threadsWorker.Count < maxThreadWorkerCount)
 77                 {
 78                     ExcuteTaskInQueen();
 79                 }
 80             }
 81         }
 82 
 83         /// <summary>
 84         /// 执行出对列的任务,加锁保护
 85         /// </summary>
 86         private static void ExcuteTaskInQueen()
 87         {
 88             lock (lockObj)
 89             {
 90                 ExcuteTaskByThread(
 91 threadStartQueue.Dequeue());
 92             }
 93         }
 94 
 95         /// <summary>
 96         /// 实现细节,这里使用BackGroudWork来实现后台线程
 97         /// 注册doWork和Completed事件,当执行一个任务前,前将任务加入到
 98         /// 工作任务集合(表示工作线程少了一个空闲),一旦RunWorkerCompleted事件被触发则将任务从工作
 99         /// 任务集合中移除(表示工作线程也空闲了一个)
100         /// </summary>
101         /// <param name="threadStart"></param>
102         private static void ExcuteTaskByThread(ThreadStart threadStart)
103         {
104             threadsWorker.Add(threadStart);
105             BackgroundWorker worker = new BackgroundWorker();
106             worker.DoWork += (o,e) => { threadStart.Invoke(); };
107             worker.RunWorkerCompleted += (o,e) => { threadsWorker.Remove(threadStart); };
108             worker.RunWorkerAsync();
109         }
110     }
View Code

然后呢再奉上有所修改的和新增的方法的代码:

 1         public List<CnblogsResult> getResult(string Html)
 2         {
 3             List<ThreadStart> StartArray = new List<ThreadStart>();
 4             Regex regexContent = new Regex("<div class=\"post_item_body\">(?<content>.*?)<div class=\"clear\"></div>",RegexOptions.Singleline);//获取单个随笔数据
 5             if (regexContent.IsMatch(Html))
 6             {
 7                 MatchCollection blog = regexContent.Matches(Html);
 8                 int i = 1;
 9                 foreach (Match item in blog)
10                 {
11                     chuancanshu ccs = new chuancanshu();
12                     ccs.i = i++;
13                     ccs.item = item;
14                     StartArray.Add(new ThreadStart(() =>
15                         {
16                             Cnblogs(ccs);
17                         }));
18                 }
19                 MyThreadPool.SetMaxWorkThreadCount(5);//设置每次从线程池中启动10个线程
20                 MyThreadPool.MyQueueUserWorkItem(StartArray);//启动线程池
21             }
22             return results;
23         }
View Code
 1         private void  Cnblogs(object obj)
 2         {
 3             CnblogsResult result = new CnblogsResult();
 4             Regex regexProperty = new Regex("<h3><a.*?href=\"(?<href>.*?)\".*?>(?<Title>.*?)</a></h3>.*?<a .*? class=\"lightblue\".*?>(?<Author>.*?)</a>.*?发布于.*?(?<time>.*?)<span", 5           RegexOptions.Singleline);//获取标题、时间、链接、作者等
 6             chuancanshu ccs = (chuancanshu)obj;
 7             Match item = ccs.item;
 8             int i = ccs.i;
 9             if (regexProperty.IsMatch(item.ToString()))
10             {
11                 var Property = regexProperty.Match(item.ToString());
12                 result.Title = Property.Groups["Title"].Value;
13                 result.Author = Property.Groups["Author"].Value;
14                 result.time = Property.Groups["time"].Value;
15                 result.href = Property.Groups["href"].Value;
16                 result.Rank = i;
17             }
18             results.Add(result);
19             if (getResults != null)
20             {
21                 getResults(results);
22             }
23         }
View Code
1  struct chuancanshu
2         {
3             public Match item;
4             public int i;
5         }
View Code

在这里呢,我把

        List<CnblogsResult> results = new List<CnblogsResult>();

这段这个提取出来当作公共变量了。

最后,奉上本例子的源码:点这里下载。

利用正则表达式获取博客园随笔四的更多相关文章

  1. Android – 线程池策略和Loader可以用来实现吗?

    )>如果不是什么是创建AsyncTask池的好方法,是否可能正在实施它?

  2. Node.js事件循环(Event Loop)和线程池详解

    这篇文章主要介绍了Node.js事件循环(Event Loop)和线程池详解,这篇文章比较浅显地探讨了有关事件循环的内部运作机制和技术细节,都是经过深思熟虑的,需要的朋友可以参考下

  3. Java实现手写乞丐版线程池的示例代码

    在这篇文章当中我们主要介绍实现一个非常简易版的线程池,深入的去理解其中的原理,麻雀虽小,五脏俱全,感兴趣的小伙伴快跟随小编一起学习学习吧

  4. java ThreadPoolExecutor线程池拒绝策略避坑

    这篇文章主要为大家介绍了java ThreadPoolExecutor拒绝策略避坑踩坑示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  5. Java线程池 ThreadPoolExecutor 详解

    这篇文章主要介绍了Java线程池 ThreadPoolExecutor,线程池包括线程集合、阻塞队列、拒绝策略处理器,更多相关内容需要的朋友可以参考一下

  6. 一篇文章带你搞懂Java线程池实现原理

    线程池无论是工作还是面试都是必备的技能,但是很多人对于线程池的实现原理却一知半解,并不了解线程池内部的工作原理,今天就带大家一块剖析线程池底层实现原理

  7. 详解Java线程池如何实现优雅退出

    这篇文章我们将从源码角度深度解析线程池是如何优雅的退出程序的,文中的示例代码讲解详细,对我们学习java线程池有一定帮助,需要的可以参考一下

  8. java 线程池存在的意义

    这篇文章主要介绍了java线程池存在的意义,通过多线程案例模拟锁的产生的情况展开对主题的详细介绍,具有一定的参考价值,需要的朋友可以参考一下

  9. Spring Boot使用线程池处理上万条数据插入功能

    这篇文章主要介绍了Spring Boot使用线程池处理上万条数据插入功能,使用步骤是先创建一个线程池的配置,让Spring Boot加载,用来定义如何创建一个ThreadPoolTaskExecutor,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧

  10. java线程池的四种创建方式详细分析

    这篇文章主要介绍了java线程池的四种创建方式详细分析,连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用

随机推荐

  1. 法国电话号码的正则表达式

    我正在尝试实施一个正则表达式,允许我检查一个号码是否是一个有效的法国电话号码.一定是这样的:要么:这是我实施的但是错了……

  2. 正则表达式 – perl分裂奇怪的行为

    PSperl是5.18.0问题是量词*允许零空间,你必须使用,这意味着1或更多.请注意,F和O之间的空间正好为零.

  3. 正则表达式 – 正则表达式大于和小于

    我想匹配以下任何一个字符:或=或=.这个似乎不起作用:[/]试试这个:它匹配可选地后跟=,或者只是=自身.

  4. 如何使用正则表达式用空格替换字符之间的短划线

    我想用正则表达式替换出现在带空格的字母之间的短划线.例如,用abcd替换ab-cd以下匹配字符–字符序列,但也替换字符[即ab-cd导致d,而不是abcd,因为我希望]我如何适应以上只能取代–部分?

  5. 正则表达式 – /bb | [^ b] {2} /它是如何工作的?

    有人可以解释一下吗?我在t-shirt上看到了这个:它似乎在说:“成为或不成为”怎么样?我好像没找到’e’?

  6. 正则表达式 – 在Scala中验证电子邮件一行

    在我的代码中添加简单的电子邮件验证,我创建了以下函数:这将传递像bob@testmymail.com这样的电子邮件和bobtestmymail.com之类的失败邮件,但是带有空格字符的邮件会漏掉,就像bob@testmymail也会返回true.我可能在这里很傻……当我测试你的正则表达式并且它正在捕捉简单的电子邮件时,我检查了你的代码并看到你正在使用findFirstIn.我相信这是你的问题.findFirstIn将跳转所有空格,直到它匹配字符串中任何位置的某个序列.我相信在你的情况下,最好使用unapp

  7. 正则表达式对小字符串的暴力

    在测试小字符串时,使用正则表达式会带来性能上的好处,还是会强制它们更快?不会通过检查给定字符串的字符是否在指定范围内比使用正则表达式更快来强制它们吗?

  8. 正则表达式 – 为什么`stoutest`不是有效的正则表达式?

    isthedelimiter,thenthematch-only-onceruleof?PATTERN?

  9. 正则表达式 – 替换..与.在R

    我怎样才能替换..我尝试过类似的东西:但它并不像我希望的那样有效.尝试添加fixed=T.

  10. 正则表达式 – 如何在字符串中的特定位置添加字符?

    我正在使用记事本,并希望使用正则表达式替换在字符串中的特定位置插入一个字符.例如,在每行的第6位插入一个逗号是什么意思?如果要在第六个字符后添加字符,请使用搜索和更换从技术上讲,这将用MatchGroup1替换每行的前6个字符,后跟逗号.

返回
顶部