快速业务通道

浅谈.NET下的多线程和并行计算(五)线程池基础 上

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

池(Pool)是一个很常见的提高性能的方式。比如线程池连接池等,之所以有这些池是因为线程和数 据库连接的创建和关闭是一种比较昂贵的行为。对于这种昂贵的资源我们往往会考虑在一个池容器中放置 一些资源,在用的时候去拿,在不够的时候添点,在用完就归还,这样就可以避免不断的创建资源和销毁 资源。

如果您做过相关实验的话可能会觉得不以为然,似乎开1000个线程也用不了几百毫秒。我们要这么想 ,对于一个高并发的环境来说,每一秒假设有100个请求,每个请求需要使用(开和关)10个线程,也就 是一秒需要处理1000个线程的开和关,每个线程独立堆栈1M,可以想象在这一秒中内存分配和回收是多么 夸张,这个开销不能说不昂贵。

首先,要理解线程池线程分为两类工作线程和IO线程,可以单独设置最小线程数和最大线程数:

ThreadPool.SetMinThreads(2, 2);
ThreadPool.SetMaxThreads(4, 4);

最大线程数很好理解,就是线程池最多创建这些线程,如果最大4个线程,现在这4个线程都在运行的 话,后续进来的线程只能排队等待了。那么为什么有最小线程一说法呢?其实之所以使用线程池是不希望 线程在创建后运行结束后理解回收,这样的话以后要用的时候还需要创建,我们可以让线程池至少保留几 个线程,即使没有线程在工作也保留。上述语句我们设置线程池一开始就保持2个工作线程和2个IO线程, 最大不超过4个线程。

至于线程池的使用相当简单先来看一段代码:

for (int i = 0; i < totalThreads; i++)
{
   ThreadPool.QueueUserWorkItem(o =>
   {
     Thread.Sleep(1000);
     int a, b;
     ThreadPool.GetAvailableThreads(out a, out b);
     Console.WriteLine(string.Format("({0}/{1}) #{2} : {3}", a, b,  Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("mm:ss")));
   });
}
Console.WriteLine("Main thread finished");
Console.ReadLine();

代码里面用到了一个事先定义的静态字段:

static readonly int totalThreads = 10;

代码运行结果如下:

每一个线程都休眠一秒然后输出当前线程池可用的工作线程和IO线程以及当前线程的托管ID和时间。 我们通过这段代码可以发现线程池的几个特性:

1) 线程池中的线程都是后台线程,如果没有在主线程使用ReadLine的话,程序马上会退出。

2) 线程池一开始就占用了2个线程,一秒后占用了4个线程,工作线程将会由3-6四个线程来处理。

3) 线程池最多使用了4个工作线程和0个IO线程。

那么,我们如何知道线程池中的线程都运行结束了呢,可以想到上文用过的Monitor结构:

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < totalThreads; i++)
{
   ThreadPool.QueueUserWorkItem(o =>
   {
     Thread.Sleep(1000);
     int a, b;
     ThreadPool.GetAvailableThreads(out a, out b);
     Console.WriteLine(string.Format("({0}/{1}) #{2} : {3}", a, b,  Thread.CurrentThread.ManagedThreadId, DateTime.Now.ToString("mm:ss")));
     lock (locker)
     {
       runningThreads--;
       Monitor.Pulse(locker);
     }

   });
}

lock (locker)
{
   while (runningThreads > 0)
     Monitor.Wait(locker);
}

Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadLine();

程序中用到了两个辅助字段:

static object locker = new object();

static int runningThreads = totalThreads;

程序运行结果如下:

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号