on pool

108 阅读4分钟

先讨论pool之概貌

说到池,对于java来说,我们最熟悉的莫过于线程池了。而Apache common pool虽经常使用(jedis连接池,数据库连接池),但却真是“日用而不知”。但其道理乃是共同的,毕竟法门不二。

线程池,我们常说它是资源管理,以符合我们使用场景所需要的参数定义。 所以我们不妨先看看线程池

线程池

1. 常用参数

参数意义
corePoolSize核心线程数
maximumPoolSize最大线程数
workQueue工作队列,可是做数据的暂时缓存之所
keepAliveTime存活时间
allowCoreThreadTimeOut是否允许核心线程超时
RejectedExecutionHandler拒绝策略

这些参数大抵可以分为三种

  • 资源上下限数据--corePoolSize maximumPoolSize
  • 资源的生命周期--keepAliveTime
  • 资源在使用时,当遵循如何的规定--workQueue allowCoreThreadTimeOut RejectedExecutionHandler

有以上的三种类型的参数,池的骨架,已经具备,而剩余之事乃是为其赋予筋肉。

2. 核心逻辑

  1. 池之状态
  2. 创建池中对象
  3. 销毁池中对象
  4. 安排池中对象,当如何进行工作
  5. 反馈机制,即根据池的状态,池中对象的生命周期,来及时进行处理,以维持池之稳定
  • 反馈机制,则必然先要有数据之支撑(相关数据之统计,相关状态之转变)
  • 然后再是,对其数据做出预定的逻辑处理

以上五者,同人之五官,若其有缺,则世途难行,非习得他种本领不可,以作人生之挽救。

general pool vs 线程池

线程池之结构,虽能为我们所鉴,然其亦有缺憾也。 究其固结,乃是其本身独立,而与外之服务无扰,譬如数据库,redis之类数据安放server。 而这正是general pool所要考量之处,故需更多参数加以辅佐完备逻辑值实现。

general pool

首先我们的创建有效的池中对象,因为检查对象,当视为首要之一。

池中对象的检查

  1. 检查池中对象与外界服务器正常连通。这种检查的时机比较重要,这种时机,涉及到了两种检查风格。
检查方式效果与影响
每次创建/使用时,进行检查可以确保每次都能获取有效的对象,实时性好,但可能给外服务带来多余的意义不大的请求,从而降低整个性能
周期性检查不会给外服务器多余的请求,不能确保每次都能获取有效的对象,实时性差
  1. 不能正常连通时,是否需要重试。
    • 需要重试时,重试次数,时间上的限制,也就自然而来

再者回归到资源有限上来考量。

池中的对象,就其活跃程度来衡量,可分为两类,繁忙与空闲。

繁忙者,自然不可抛弃。空闲者,则需权衡以处之。

空闲对象的处置参数

  1. 空闲对象的数量限制(可以有上下界限)
  2. 空闲对象的空闲时间限制
  3. 空闲对象当如何清除掉(这涉及到池中的清除机制)

清除机制

  1. 前提条件,池中需要有统计数据,来区分各种状态的对象,以及对应的数量。
  2. 清除机制一般是一个定时任务,进行定期的扫描,判断,处理,维护池的稳定。
    • 定时任务的周期时间
    • 扫描池中对象的方式(比如,全部都扫描,还是只扫描一部分,池中对象的遍历方式(顺序还是倒序))
    • 判断池中对象是否可以清除
    • 如不可清除,是否需要检查当前对象的有效性,是否需要激活它,再次使用
    • 清除完毕后,是否有违背池的定义(比如池中对象的数目是否还满足最小值,池中空闲数量是否还满足最小值)

至此general pool之全貌,虽未尽睹,但正如画龙之法,龙之鳞爪已露,至于身躯,本当深藏云中,乃为善也。