并发编程(十七):Excutor与ThreadPoolExcutor


学习资料

《Java并发编程的艺术》第10章 10.1~10.2


1.Excutor简介

从JDK 5开始,把工作单元与执行机制分离开来。工作单元包括 Runnable 和 Callable ,而执行机制由 Executor 框架提供

1.1 两级调度模型

在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程,操作系统内核将这些线程映射到

硬件处理器上:

1.2 Executor框架的结构和成员

结构

主要由三大部分组成:

  • 任务:Runnable 接口或 Callable 接口
  • 任务的执行:核心接口Executor ,子接口ExcutorService接口,子接口实现类:ThreadPoolExecutorScheduledThreadPoolExecutor
  • 异步计算结果:Future 和实现类 FutureTask 类

相关类和接口:

Executor框架使用流程:

  • submit()返回Future接口,execut()无返回值
  • Future.get()等待任务完成,Future.cancel()取消任务执行

成员

  1. ThreadPoolExecutor:线程池核心实现类(后有详解)

    可用工厂类Executors创建,有三种类型:SingleThreadExecutorFixedThreadPoolCachedThreadPool

  2. ScheduledThreadPoolExecutor

    可用工厂类Executors创建,可创建两种类型:

    • ScheduledThreadPoolExecutor:多个后台线程

    • SingleThreadScheduledExecutor:单个后台线程

  3. Future接口:表示异步计算结果,submit()返回

  4. Runnable接口和Callable接口 :都可以被工作线程执行

    除了可以自己创建实现Callable接口的对象外,还可以使用工厂类Executors来把一个

    Runnable包装成一个Callable:

    public static Callable<Object> callable(Runnable task);
    public static <T> Callable<T> callable(Runnable task,T result); //result为返回的内容
    

2.ThreadPoolExecutor详解

Executors可以创建多种线程池:

  • WorkStealingPool
  • ScheduledThreadPool
  • 和以下三种

2.1 FixedThreadPool

可重用固定线程数线程池,核心数=最大线程数

内部使用LinkedBlockingQueue无界队列,keepAliveTime(0L)和maximumPoolSize无效,不会拒绝任务

运行示意图:

2.2 SingleThreadExecutor

使用单个worker线程的Executor,corePoolSize=maximumPoolSize=1

内部使用LinkedBlockingQueue无界队列

运行示意图:

2.3 CachedThreadPool

会根据需要创建新线程的线程池,相当于没有使用线程池

源码如下:

public static ExecutorService newCachedThreadPool() { 
	return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); 
}
  • corePoolSize被设置为0,即corePool为空;

  • maximumPoolSize被设置为 Integer.MAX_VALUE,即maximumPool是无界的;

  • keepAliveTime设置为60L,空闲超过60秒的线程会被终止;SynchronousQueue.poll(keepAliveTime,TimeUnit.NANOSECONDS)

  • 内部使用 SynchronousQueue 作为线程池的工作队列,不保存元素;

运行示意图:

每个插入(offer)操作必须等待另一个线程的对应移除(poll)操作,反之亦然


posted @ 2021-03-11 21:27  菜鸟kenshine  阅读(257)  评论(0编辑  收藏  举报