`
fatherican
  • 浏览: 52980 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

OpenNMS全接触-线程池(五)

 
阅读更多

转载于:http://njulinq.blog.51cto.com/1257169/283585

为提高系统效率,OpenNMS在很多模块中启用了多线程,并通过线程池来对这些线程进行管理。而且具体线程数可以通过配置文件进行配置,例如在%OpenNMS_HOME%/etc/capsd-configuration.xml文件中,就可以对网络服务发现和服务重新扫描的线程数进行配置:

  1. <capsd-configuration
  2. rescan-frequency="86400000"
  3. initial-sleep-time="30000"
  4. max-suspect-thread-pool-size="10"
  5. max-rescan-thread-pool-size="10">

其中的max-suspect-thread-pool-size就定义了可以同时对多少个IP地址进行服务扫描,而max-rescan-thread-pool-size则定义了可以同时对多少个IP进行服务重新扫描。

本文将从源码来剖析其线程池的实现机制。在OpenNMS的代码中,是通过RunnableConsumerThreadPool来实现线程池的,我们首先看下该类是如何被使用的。

  1. m_runner=newRunnableConsumerThreadPool("TestPool",0.6f,1.0f,10);

首先创建一个线程池对象,构造函数的4个参数,第一个和最后一个比较好解释,第一个就是线程池名字,给个名字主要在日志中比较好区分各个线程的执行轨迹,最后一个参数就是定义线程池的大小。第二个和第三个参数稍微解释下,它们分别定义了两个分水岭(或称预置),其实就是当前线程池负载情况。为解释这两个参数,首先需要定义几个概念:

  1. 等待调度对象: 等待调度对象就是所有需要执行的对象,它们最终都要进入线程池由线程池分配一个线程来执行
  2. 线程池: 线程池是所有线程的一个容器,它同时负责线程的创建、调度及销毁
  3. 线程: 线程不同于等待调度对象,它是物理可执行的对象,它负责最终执行等待调度对象,而且一般情况下,线程数都小于等待调度对象数目

有了上面几个概念,就比较好解释那两个参数了,这两个参数分别成为低水印值和高水印值,它的取值实际上是等待调度对象与线程池中线程数的比值。低水印值的含义是当比值小于这个值后,即等待调度对象少于线程池中线程数且达到某个度时,则需要销毁一些线程池中的线程数,以减少系统负载。而高水印值的含义则是当比值大于这个值后,在不超出线程池大小的前提下,增加线程池中线程数。所以一般情况下高水印值都是取1。

下面开始深入线程池的内部了,首先线程池是用了一个先进先出队列来保存等待调度对象,

  1. privateSizingFifoQueue<Runnable>m_delegateQ;

用一个简单的数组来保存线程池,

  1. privateFiber[]m_fibers;
  2. privatefloatm_hiRatio;
  3. privatefloatm_loRatio;
  4. privateintm_maxSize;

上面除了保存线程的数组外,另外三个变量依次表示高水印值,低水印值及线程池大小。

在下一篇文章中将介绍线程池的具体操作流程。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics