【视听盛宴】Java线程池(2013.8.28)

来源:互联网 发布:美国海军 知乎 编辑:程序博客网 时间:2024/05/21 05:19

公司组织了一场关于Java线程池的讲座,我对Java不甚了解,对Java线程池就更不知道了。根据演讲的PPT,加上自己的理解写成了这篇文章,其中不免有错误的地方,还望大家指正。


使用Java线程池的优点

当我们使用单线程时,不仅处理速度慢,而且极不安全,试想,如果这条线程由于某些原因而挂掉,将导致下面所有的任务都没法完成,Java线程池的使用就规避了这样的风险,而且也提供了系统资源的利用率,具体来说,使用Java线程池有如下三个优点:

  1. 提供系统稳定性,避免一个线程的挂掉而影响到整个系统
  2. 重复利用已创建的线程,不仅降低了反复创建和销毁线程造成的资源消耗,也提高了系统的响应时间
  3. 对线程进行统一管理,提高线程的可管理性

创建Java线程池语句

创建Java线程池的语句如下:

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit,runnableTaskQueue, rejectedExecutionHandler);

要理解其中参数的意义,先来看一下Java线程池处理新任务的基本流程是怎样的,如下图:


我们根据上面的流程逐一介绍这些参数。当用户提交一个新任务时,Java线程池首先判断池中的存活线程数是否大于corePoolSize(Java线程池中最小存活线程数),若不大于,则直接创建一个新的线程来执行这个任务,而不管现有线程是否空闲;若大于,则判断runnableTaskQueue(由等待执行的任务组成的阻塞队列)是否达到了阻塞的最大值,若小于,则将该任务放在runnableTaskQueue中;若大于,则判断Java线程池中存活的线程数是否大于maximumPoolSize(Java线程池中最大存活线程数),若小于,则创建一个新的线程来执行这个任务(此时,无空闲线程,如有空闲线程则直接用空闲线程执行);若大于,则按照rejectedExecutionHandler(饱和策略)处理提交的新任务。

其中runnableTaskQueue可以采用不同的策略存储任务,学过操作系统的人应该对这些策略很熟悉,在这就不具体介绍了。而JDK1.5提供了四种rejectedExecutionHandler策略:

1.    AbortPolicy:直接抛出异常

2.    DiscardPolicy:不处理,直接丢弃

3.    CallerRunsPolicy:只用调用者所在线程来执行任务

4.    DiscardPolicy:丢弃阻塞队列里最新提交的任务,同时执行当前任务

也可以自定义rejectedExecutionHandler策略。

除了上面介绍的四个参数外还有两个参数:keepAliveTime,和timeUnit,这两个参数用来控制线程的存活时间,第一个是数值,第二个是单位。

向Java线程池提交任务

向Java线程池提交任务有两种方法:execute和submit,两者的区别是前者没有返回值,而后者有。

关闭Java线程池

关闭Java线程池也有两种方法:shutdown和shutdownNow,前者会等待正在执行的任务执行完毕再关闭Java线程池,而后者直接关闭Java线程池,从而会导致所有任务中断。

监控Java线程池常用的属性

我们可以通过监控Java线程池的属性来查看Java线程池的运行状态,从而更有效的配置Java线程池,可监控的属性如下:

  1. taskCount:Java线程池需要执行的任务数量,采用累加
  2. completedTaskCount: Java线程池在运行过程中已完成的任务数量
  3. largestPoolSize: Java线程池曾创建过的最大线程数
  4. getPoolSize:得到Java线程池的线程数量
  5. getActiveCount:获得活动的线程数

最后,还是要申明一点,这篇文章是在对Java不熟悉的情况下写的,肯定会有理解错误的地方,欢迎大家批评指教!

原创粉丝点击