【IT168技术文档】
转载自Jeff Zhao的博客
线程池是一个重要的概念。不过我发现,关于这个话题的讨论似乎还缺少了点什么。作为资料的补充,以及今后文章所需要的引用,我在这里再完整而又简单地谈一下有关线程池,还有.NET中各种线程池的基础。更详细的内容就不多作展开了,有机会我们再详细讨论这方面的细节。这次,还是一个“概述”性质的,希望可以说明白这方面问题的一些概念。
线程池的作用
其实“线程池”就是用来存放“线程”的对象池。
在程序中,如果某个创建某种对象所需要的代价太高,同时这个对象又可以反复使用,那么我们往往就会准备一个容器,用来保存一批这样的对象。于是乎,我们想要用这种对象时,就不需要每次去创建一个,而直接从容器中取出一个现成的对象就可以了。由于节省了创建对象的开销,程序性能自然就上升了。这个容器就是“池”。很容易理解的是,因为有了对象池,因此在用完对象之后必须有一个“归还”的动作,这样便可以把对象放回池中,下次需要的时候就可以再次拿出来使用了。
例如,我们在使用ADO.NET连接SQL Server时,.NET框架就会自动帮我们维护一个连接池,这就是因为重新创建一个连接的代价相对比较高昂,“复用”就显得比较划算了。不过有些朋友可能会说,我们明明是每次都创建一个SqlConnection对象,哪里有“复用”啊?这是因为.NET框架中把“连接池”做透明了,对于程序员完全隐藏了这个概念。每次我们虽然创建的是新的SqlConnection对象,但是这个对象内部占用的“数据库连接”还是会复用的。为什么总是强调用完SqlConnection对象后要及时“关闭”(Dispose或Close)呢?其实这里并没有断开数据库连接,只是把这个连接放回了连接池。等到下次创建新的SqlConnection对象时,这个连接又可以拿出来用了。
既然我们每次都是从池中获取对象,那么这些对象是由谁来创建,又是什么时候创建的呢?这个就要根据不同情况由各对象池来自行实现了。例如,可以在创建对象池的时候指定池内对象数量,并且一下子全部创建好,当然您也可以在得到请求时,如果发现池中已经没有剩余对象时创建。您也可以“事前”先准备一部分,“事中”根据需要再继续补充。还可以做得“智能”一些,例如,根据实际情况添加或删除一些对象,甚至对需求“走势”进行“预测”,在空闲时便创建更多的对象以备“不时之需”。各中变化难以言尽。
当然,它们的原理和目的是类似的。相信上面这段文字也已经讲清了“线程池”的作用:因为创建一个线程的代价较高,因此我们使用线程池设法复用线程。就是这么简单。