深入浅出多线程系列之三:线程池

简介:

线程池:

每一个线程默认会被分配1MB的内存,在C#中,这些都是实打实的分配的,当一个线程启动的时候,为了分配临时堆栈大约需要花费几百微秒的时间。

线程池通过循环利用线程可以让你更高效的利用线程。

 

线程池就像外包的劳务队一样,有任务给他们,他们会管理劳务工的一切,你不需要去花时间去找单个劳务工,然后完成任务就解雇她,

对劳务队而言,劳务工完成了你的这个任务,还是会回到自己的团队中的,劳务工的管理也不需要你去负责,因为这由劳务队处理了,

如果任务太多了,劳务队会自己招一个劳务工,如果还不够就继续招,但是如果任务比较少,而劳务工又比较多的话,对不起,劳务队的管理人员就会解雇一部分劳务工了。

 

有很多方法可以进入线程池:

  1. 借助Task Parallel Library(framework 4.0)
  2. 调用ThreadPool.QueueUserWorkItem
  3. 借助异步委托。
  4. 借助BackgroundWorker.  

下面的一些构造间接的使用了线程池:

  1. WCF,Remoting,Asp.net, asmx web services应用程序。
  2. System.Timers.Timer  System.Threading.Timer.
  3. framework的一些异步方法,例如WebClient 类,和大部分BeginXXX方法。
  4. PLINQ 

使用线程池的一些问题:

  1. 不可以设置一个线程池线程的名字。
  2. 线程池线程全部都是后台线程。
  3. 阻塞一个线程池线程可能会触发创建一个新线程,除非你调用ThreadPool.SetMinThreads方法。

  

通过Thread.CurrentThread.IsThreadPoolThread属性可以查询一个线程是否是线程池线程。

 

实战ThreadPool

1:通过Task使用线程池:

复制代码
        public   static   void  MainThread()
        {
            Task
< string >  task  =  Task.Factory.StartNew < string >
                (() 
=>  DownloadString( " http://www.google.com " ));

            
// DoSomething
             string  result  =  task.Result;
        }

        
static   string  DownloadString( string  uri)
        {
            
using  (var wc  =   new  System.Net.WebClient())
                
return  wc.DownloadString(uri);
        }
复制代码

 当查询task.Result的时候线程阻塞,等待task返回Result。

 

2:通过ThreadPool.QueueUserWorkItem

复制代码
        public   static   void  MainThread()
        {
            ThreadPool.QueueUserWorkItem(Go);
            ThreadPool.QueueUserWorkItem(Go, 
123 );
            
            Console.ReadLine();
        }

        
static   void  Go( object  data)
        {
            Console.WriteLine(
" Hello from the thread pool!  "   +  data);
        }
复制代码

Output:

Hello from the thread pool!

Hello from the thread pool! 123

 

3:借助委托的BeginXXX方法:

复制代码
        public   static   void  MainThread()
        {
            Func
< string int >  method  =  Work;
            method.BeginInvoke(
" test " , Done, method);
        }

        
static   int  Work( string  s) {  return  s.Length; }

        
static   void  Done(IAsyncResult cookie)
        {
            var target 
=  (Func < string int > )cookie.AsyncState;
            
int  result  =  target.EndInvoke(cookie);
             Console.WriteLine(
" String length is: "   +  result);
        }
复制代码

在这里将method当作参数进行传递后,在cookie的AsyncState中就可以使用传递的method了,

因为cookie.AsyncState类型是object,所以需要进行转换,然后调用EndInvoke方法来获取结果。






本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/05/22/2052561.html,如需转载请自行联系原作者
目录
相关文章
|
13天前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
25天前
|
存储 缓存 NoSQL
Redis单线程已经很快了6.0引入多线程
Redis单线程已经很快了6.0引入多线程
31 3
|
27天前
|
消息中间件 安全 Linux
线程同步与IPC:单进程多线程环境下的选择与权衡
线程同步与IPC:单进程多线程环境下的选择与权衡
57 0
|
1月前
|
Java 调度 C#
C#学习系列相关之多线程(一)----常用多线程方法总结
C#学习系列相关之多线程(一)----常用多线程方法总结
|
1月前
|
安全 编译器 C#
C#学习相关系列之多线程---lock线程锁的用法
C#学习相关系列之多线程---lock线程锁的用法
|
1月前
|
Java C#
C#学习系列相关之多线程(五)----线程池ThreadPool用法
C#学习系列相关之多线程(五)----线程池ThreadPool用法
|
1月前
|
数据采集 存储 Java
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
「多线程大杀器」Python并发编程利器:ThreadPoolExecutor,让你一次性轻松开启多个线程,秒杀大量任务!
|
26天前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
71 0
|
21天前
|
安全 Java 容器
Java并发编程:实现高效、线程安全的多线程应用
综上所述,Java并发编程需要注意线程安全、可见性、性能等方面的问题。合理使用线程池、同步机制、并发容器等工具,可以实现高效且线程安全的多线程应用。
14 1
|
21天前
|
JavaScript 前端开发
JS 单线程还是多线程,如何显示异步操作
JS 单线程还是多线程,如何显示异步操作
22 2

热门文章

最新文章