为什么要用线程池?
【程序编程相关:阿尔卡特朗讯合并 业内合并狂潮的导火索?】诸如 web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 http.ftp 或 pop).通过 jms 队列或者可能通过轮询数据库.不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的. 【推荐阅读:私登他人家庭Wi-Fi网 美国一男子被罚】
【扩展信息:Wi-Fi手机价格偏高 销售量将会受到影】构建服务器应用程序的一个过于简单的模型应该是:每当一个请求到达就创建一个新线程,然后在新线程中为请求服务.实际上,对于原型开发这种方法工作得很好,但如果试图部署以这种方式运行的服务器应用程序,那么这种方法的严重不足就很明显.每个请求对应一个线程(thread-per-request)方法的不足之一是:为每个请求创建一个新线程的开销很大;为每个请求创建新线程的服务器在创建与销毁线程上花费的时间与消耗的系统资源要比花在处理实际的用户请求的时间与资源更多. 除了创建与销毁线程的开销之外,活动的线程也消耗系统资源.在一个 jvm 里创建太多的线程可能会导致系统由于过度消耗内存而用完内存或“切换过度”.为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时刻处理的请求数目. 线程池为线程生命周期开销问题与资源不足问题提供了解决方案.通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上.其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟.这样,就可以立即为请求服务,使应用程序响应更快.而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足. 线程池的替代方案线程池远不是服务器应用程序内使用多线程的唯一方法.如同上面所提到的,有时,为每个新任务生成一个新线程是十分明智的.然而,如果任务创建过于频繁而任务的平均处理时间过短,那么为每个任务生成一个新线程将会导致性能问题.
另一个常见的线程模型是为某一类型的任务分配一个后台线程与任务队列.awt 与 swing 就使用这个模型,在这个模型中有一个 gui 事件线程,导致用户界面发生变化的所有工作都必须在该线程中执行.然而,由于只有一个 awt 线程,因此要在 awt 线程中执行任务可能要花费相当长时间才能完成,这是不可取的.因此,swing 应用程序经常需要额外的工作线程,用于运行时间很长的.同 ui 有关的任务. 每个任务对应一个线程方法与单个后台线程(single-background-thread)方法在某些情形下都工作得非常理想.每个任务一个线程方法在只有少量运行时间很长的任务时工作得十分好.而只要调度可预见性不是很重要,则单个后台线程方法就工作得十分好,如低优先级后台任务就是这种情况.然而,大多数服务器应用程序都是面向处理大量的短期任务或子任务,因此往往希望具有一种能够以低开销有效地处理这些任务的机制以及一些资源管理与定时可预见性的措施.线程池提供了这些优点. 工作队列就线程池的实际实现方式而言,术语“线程池”有些使人误解,因为线程池“明显的”实现在大多数情形下并不一定产生我们希望的结果.... 下一页