该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-06
前段时间一个项目中因为涉及大量的线程开发,把jdk cocurrent的代码重新再过了一遍。这篇文章中主要是记录一下学习ThreadPoolExecutor过程中容易被人忽略的点,Doug Lea的整个类设计还是非常nice的 先看一副图,描述了ThreadPoolExecutor的工作机制: 整个ThreadPoolExecutor的任务处理有4步操作: 再提供一个btrace脚本,分析线上的thread pool容量规划是否合理,可以运行时输出poolSize等一些数据。 运行结果: 说明: 1. poolSize 代表为当前的线程数 2. largestPoolSize 代表为历史最大的线程数 3. queueSize 代表blockqueue的当前堆积的size 4. reject count 代表在1000ms内的被reject的数量 这是我对ThreadPoolExecutor使用过程中的一些经验总结,希望能对大家有所帮助,如有描述不对的地方欢迎拍砖。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-12-06
如果每天有十万条线程需运行,用这个方法可不可靠?就是如果出错,之前的数据就丢失了,因为不象JMS那样,有保存的功能。
|
|
返回顶楼 | |
发表时间:2011-12-06
paulwong 写道 如果每天有十万条线程需运行,用这个方法可不可靠?就是如果出错,之前的数据就丢失了,因为不象JMS那样,有保存的功能。
ThreadPoolExecutor不会帮你执行数据的持久化,它只是一个工具,一个执行器 你提的需求,应该需要一整套的技术来完成你需要的高可用的需求,而ThreadExecutorPool更面向的应该是单机高性能的处理, jdk cocurrent包中的基本都是这个定位 |
|
返回顶楼 | |
发表时间:2011-12-06
如果每天十万条线程这种级别的,是否建议使用ThreadExecutorPool?
|
|
返回顶楼 | |
发表时间:2011-12-06
paulwong 写道 如果每天十万条线程这种级别的,是否建议使用ThreadExecutorPool?
10W个线程 or 10W个任务? jvm线程创建需要占用一定的内存,普通服务器不可能创建达到上W级的线程。 |
|
返回顶楼 | |
发表时间:2011-12-06
agapple 写道 paulwong 写道 如果每天十万条线程这种级别的,是否建议使用ThreadExecutorPool?
10W个线程 or 10W个任务? jvm线程创建需要占用一定的内存,普通服务器不可能创建达到上W级的线程。 就是queueSize这里可能有十万条处于等待中。 |
|
返回顶楼 | |
发表时间:2011-12-06
paulwong 写道 agapple 写道 paulwong 写道 如果每天十万条线程这种级别的,是否建议使用ThreadExecutorPool?
10W个线程 or 10W个任务? jvm线程创建需要占用一定的内存,普通服务器不可能创建达到上W级的线程。 就是queueSize这里可能有十万条处于等待中。 1. 如果10W条,评估下内存占用,不暴jvm内存的话,完全没啥问题 2. 如果内存占用过大,可考虑扩展实现一个RejectedExecutionHandler,出现满任务时hold住后续的任务提交,进行一个阻塞操作 |
|
返回顶楼 | |
发表时间:2011-12-06
最后修改:2011-12-06
agapple 写道 paulwong 写道 agapple 写道 paulwong 写道 如果每天十万条线程这种级别的,是否建议使用ThreadExecutorPool?
10W个线程 or 10W个任务? jvm线程创建需要占用一定的内存,普通服务器不可能创建达到上W级的线程。 就是queueSize这里可能有十万条处于等待中。 1. 如果10W条,评估下内存占用,不暴jvm内存的话,完全没啥问题 2. 如果内存占用过大,可考虑扩展实现一个RejectedExecutionHandler,出现满任务时hold住后续的任务提交,进行一个阻塞操作 好主意! 另,Doug Lea大师的设计非常非常棒, 比如 RejectedExecutionHandler中的 4. CallsRun 直接让原先的client thread做为worker线程,进行执行 仅在当前线程上下文中执行该runnable的run()方法 即非常巧妙有趣的处理了RejectedExecution 很帅啊,谁说runnable/thread只能start呢? |
|
返回顶楼 | |
发表时间:2011-12-06
如果正在执行的task是个很耗时的任务,且它没有安乐死的方法.这是用户已经没有耐心在继续等待了,也不想让它继续占用线程池的工作线程;所以想强杀所在线程(强杀无副作用:不会造成死锁资源泄露等),然后再补缺.大家觉得这样的线程池怎么样?
|
|
返回顶楼 | |
发表时间:2011-12-06
引用 (我曾经配置了corePoolSize=1, maximumPoolSize=20, blockqueue为无界队列,最后就成了单线程工作的pool。典型的配置错误)
线程池应该还要提供一种策略给我们选择----是优先启动新线程还是优先使用队列。否则用有界或是无界队列,都是先把队列填满了才再开新线程。导致的一个结果是我们不得不用SynchronousQueue来作为任务队列。 |
|
返回顶楼 | |