Java理论与实践: 线程池与工作队列 - 编程入门网
则
只要您遵循几条简单的准则,线程池可以成为构建服务器应用程序的极其有 效的方法: 不要对那些同步等待其它任务结果的任务排队。这可能会导致上面所描述的 那种形式的死锁,在那种死锁中,所有线程都被一些任务所占用,这些任务依次 等待排队任务的结果,而这些任务又无法执行,因为所有的线程都很忙。 在为时间可能很长的操作使用合用的线程时要小心。如果程序必须等待诸如 I/O 完成这样的某个资源,那么请指定最长的等待时间,以及随后是失效还是将 任务重新排队以便稍后执行。这样做保证了:通过将某个线程释放给某个可能成 功完成的任务,从而将最终取得 某些进展。 理解任务。要有效地调整线程池大小,您需要理解正在排队的任务以及它们 正在做什么。它们是 CPU 限制的(CPU-bound)吗?它们是 I/O 限制的(I/O- bound)吗?您的答案将影响您如何调整应用程序。如果您有不同的任务类,这 些类有着截然不同的特征,那么为不同任务类设置多个工作队列可能会有意义, 这样可以相应地调整每个池。 Java理论与实践: 线程池与工作队列(4)时间:2010-12-20 IBM Brian Goetz调整池的大小 调整线程池的大小基本上就是避免两类错误:线程太少或线程太多。幸运的 是,对于大多数应用程序来说,太多和太少之间的余地相当宽。 请回忆:在应用程序中使用线程有两个主要优点,尽管在等待诸如 I/O 的慢 操作,但允许继续进行处理,并且可以利用多处理器。在运行于具有 N 个处理 器机器上的计算限制的应用程序中,在线程数目接近 N 时添加额外的线程可能 会改善总处理能力,而在线程数目超过 N 时添加额外的线程将不起作用。事实 上,太多的线程甚至会降低性能,因为它会导致额外的环境切换开销。 线程池的最佳大小取决于可用处理器的数目以及工作队列中的任务的性质。 若在一个具有 N 个处理器的系统上只有一个工作队列,其中全部是计算性质的 任务,在线程池具有 N 或 N+1 个线程时一般会获得最大的 CPU 利用率。 对于那些可能需要等待 I/O 完成的任务(例如,从套接字读取 HTTP 请求的 任务),需要让池的大小超过可用处理器的数目,因为并不是所有线程都一直在 工作。通过使用概要分析,您可以估计某个典型请求的等待时间(WT)与服务时 间(ST)之间的比例。如果我们将这一比例称之为 WT/ST,那么对于一个具有 N 个处理器的系统,需要设置大约 N*(1+WT/ST) 个线程来保持处理器得到充分利 用。 处理器利用率不是调整线程池大小过程中的唯一考虑事项。随着线程池的增 长,您可能会碰到调度程序、可用内存方面的限制,或者其它系统资源方面的限 制,例如套接字、打开的文件句柄或数据库连接等的数目。 无须编写您自己的池 Doug Lea 编写了一个优秀的并发实用程序开放源码库 util.concurrent , 它包括互斥、信号量、诸如在并发访问下执行得很好的队列和散列表之类集合类 以及几个工作队列实现。该包中的 PooledExecutor 类是一种有效的、广泛使用 的以工作队列为基础的线程池的正确实现。您无须尝试编写您自己的线程池,这 样做容易出错,相反您可以考虑使用 util.concurrent 中的一些实用程序。参 阅 参考资料以获取链接和更多信息。 util.concurrent 库也激发了 JSR 166,JSR 166 是一个 Java 社区过程 (Java Community Process (JCP))工作组,他们正在打算开发一组包含在 java.util.concurrent 包下的 Java 类库中的并发实用程序,这个包应该用于 Java 开发工具箱 1.5 发行版。 结束语 线程池是组织服务器应用程序的有用工具。它在概念上十分简单,但在实现 和使用一个池时,却需要注意几个问题,例如死锁、资源不足和 wait() 及 notify() 的复杂性。如果您发现您的应用程序需要线程池,那么请考虑使用 util.conc |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |