Java并发编程的艺术(十一)——Executor与线程池

Executor框架简介

从JDK5开始,把工作单元和执行机制分离开来了,工作的单元包括Runnable和Callable,执行机制就是由Executor框架提供。

Executor两级调度模型

HotSpot虚拟机将Java线程映射为操作系统的线程。

在上层,Java多线程程序将应用分解为多个任务,然后由用户级的调度器Executor将这些任务映射为固定数量的线程。

在底层,操作系统将这些线程映射到硬件处理器上。
在这里插入图片描述

Executor结构与成员

结构由三大部分组成:

  • 任务:包括被执行任务所需要实现的接口:Runnable, Callable。
  • 任务的执行:核心接口时Executor,以及继承了它的ExecutorService接口。ExecutorService有两个关键类,ThreadPoolExecutor和ScheduledThreadPoolExecutor。
  • 执行结果:包括Future接口及其实现类FutureTask。

在这里插入图片描述

线程池相关

1.FixedThreadPool

在这里插入图片描述

代码实现

public static ExecutorService newFixedThreadPool(int nThreads){
    return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}

这里把keepAliveTime设置为0L,超过核心数的多余的线程会立即停止。

特点

  1. 线程数固定。
  2. corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads,则超出无法创建超出核心数量的工作线程。
  3. 堵塞队列采用LinkedBlockingQueue,无界队列。
  4. 采用无界队列,就不会拒绝任务,同时maximumPoolSize和keepAliveTime参数将无效。

2.SingleThreadPool

在这里插入图片描述

使用方法

public static ExecutorService newSingleThreadExecutor(){
    return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}

特点

  1. 只有一条工作线程。
  2. 采用阻塞队列为LinkedBlockingQueue。

3.CachedThreadPool

在这里插入图片描述

代码实现

public static ExecutorService newCachedThreadPool(){
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
}

特点

  1. 可以无限扩大。
  2. 适合处理执行时间小任务。
  3. 核心线程数为0,而最大线程数无限大,这样线程数量可以无限扩大。
  4. 超时时间时60s,这样空闲线程等待60秒后就会被销毁。
  5. 阻塞队列采用SynchronousQueue。这个队列没有存储空间,所以,如果有任务到来,就不会被入队,直接新建线程拿去运行。

4.ScheduledThreadPool

在这里插入图片描述

特点

  1. 用于执行延时或者定时任务
  2. 采用DelayQueue阻塞队列,内部其实由PriorityQueue实现,并根据时间排序,时间相同则根据序号排序,也是无界队列。
  3. 需要确定任务开始时间,任务序列号,任务执行的时间间隔。
  4. 如果是周期任务,则执行完又放回队列。
posted @ 2020-11-14 11:21  lippon  阅读(58)  评论(0编辑  收藏  举报