Java并发基础(二)-线程池基础

来源:互联网 发布:直播平台软件开发 编辑:程序博客网 时间:2024/05/16 14:29

1. 前言

从Java 1.5 开始,并发包里面提供了Executors类,这个类提供了几种线程池的实现。下面对ExecutorService以及几种线程池进行说明。

2.ExecutorService

ExecutorService 接口继承自 Executor 接口,它提供了更丰富的实现多线程的方法。

ExecutorService的生命周期有三种状态:

  • 运行 创建之后便进入运行状态
  • 关闭 当调用shutdown()方法之后就进入关闭状态
  • 终止 调用shutdown(),当已有的任务执行完毕之后就进入终止状态

shutdown方法会”平滑的”关闭,也就是说,会不在接受新的任务,而已接受的任务(不管是执行中还是等待中),都会继续。

3. Executors

  • newFixedThreadPool,创建一个固定数目的线程池。
  • newCachedThreadPool,创建一个可缓冲线程的线程池,也就是先查看有没有以前创建的可用的线程,如果有就重用,没有就创建新的,线程空闲等待的时间是60s,如果60s之内没有重用,就会被回收。
  • newScheduledThreadPool,创建调度性线程池,可以延迟执行或者周期性执行
  • newSingleThreadExecutor,创建一个单一工作线程的线程池,

上面的四种线程池是从Java 1.5 开始提供的。在Java 1.8 当中,提供了一种新的线程池。

  • newWorkStealingPool,实现了工作窃取算法的线程池,这个,我们现在暂且不说。

而Java 1.5 提供的四种线程池,newFixedThreadPool,newCachedThreadPool,都是由ThreadPoolExecutor来实现的。newScheduledThreadPool是由ThreadPoolExecutor的子类ScheduledThreadPoolExecutor来实现的。newSingleThreadExecutor是由DelegatedScheduledExecutorService(代理类来实现的)。

4. ThreadPoolExecutor

其涉及到核心变量如下:

  • corePoolSize 核心线程数
  • maximumPoolSize 最大线程数
  • keepAliveTime 当线程池中的线程数超过corePoolSize的空闲线程最大存活时间
  • TimeUnit keepAliveTime时间单位
  • workQueue 阻塞任务队列
  • threadFactory 新建线程工厂
  • RejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理

其生命周期和ExecutorService稍有不同。如下
这里写图片描述

关于ThreadPoolExecutor的实现原理,可以看一下几篇文章。

  • ThreadPoolExecutor简介与源码分析
  • Java 线程池 - ThreadPoolExecutor 源码分析

5. ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor实现了ScheduledExecutorService接口,实现了调度的功能。

  • schedule 延迟一段时间执行
  • scheduleAtFixedRate 连续周期行执行
  • scheduleWithFixedDelay 以固定的延迟执行

关于ScheduledThreadPoolExecutor更多的资料可以看下面文章:

  • 深度解析Java8 – ScheduledThreadPoolExecutor源码解析
  • Android Java 线程池 ScheduledThreadPoolExecutor源码篇
  • 自行google或者查看源码以及阅读源码注释

6. DelegatedExecutorService

这个就是ExecutorService的一个代理类,可以自行查阅源码。

7. 排队策略

说道线程池,肯定是存在排队策略的。下面简单介绍下几种排队策略。

  • 直接提交 缓冲队列采用 SynchronousQueue,将任务直接交给线程处理而不保存他们 newCachedThreadPool
  • 无界队列 典型的便是采用预定义容量的 LinkedBlockingQueue,所有的corePoolSize线程都在工作中,新任务将提交到缓存队列中。 newSingleThreadExecutor
  • 有界队列 当使用有限的 maximumPoolSizes 时,一般缓冲队列使用 ArrayBlockingQueue,并制定队列的最大长度

2 2