0
点赞
收藏
分享

微信扫一扫

【并发编程】Executor架构介绍

【并发编程】Executor架构介绍_构造函数



【并发编程】Executor架构介绍_构造函数_02


要点总结

Executor表示的任务类型

主要有3种:

  1. Runnable: 无返回值,无异常抛出;
  2. Callable:有返回值,可以异常抛出;
  3. Future任务: 表示异步计算,可取消; 通过newTaskFor()方法,将Runnable/Callable任务转换为Future任务;

【并发编程】Executor架构介绍_实现原理_03


【并发编程】Executor架构介绍_异步任务_04


【并发编程】Executor架构介绍_实现原理_05

【并发编程】Executor架构介绍_构造函数_06


【并发编程】Executor架构介绍_实现原理_07


由上面可知: FutureTask既是Runnable任务,也是Future任务;


【并发编程】Executor架构介绍_异步任务_08


【并发编程】Executor架构介绍_构造函数_09


【并发编程】Executor架构介绍_异步任务_10


Future任务的创建方法


Future任务的特点:

  1. 异步计算:通过get()方法来获取异步计算的结果;
  2. 可取消;

【并发编程】Executor架构介绍_实现原理_05


创建Future任务

主要有2种方式:

  1. 通过FutureTask构造函数来创建;(事实上,FutureTask是Future接口的唯一实现)
  2. 通过ExecutorService的submit()方法来创建;


  • 方式1:通过FutureTask的构造函数来创建;

【并发编程】Executor架构介绍_构造函数_12


  • 方式2:通过ExecutorService的submit()方法来创建;

【并发编程】Executor架构介绍_实现原理_13

【并发编程】Executor架构介绍_实现原理_14

【并发编程】Executor架构介绍_实现原理_15

【并发编程】Executor架构介绍_异步任务_16


由上面可知:ExecutorService.submit()最终还是使用FutureTask构造函数来创建Future任务;

Executor框架,任务提交的2种方式

  1. Executor接口:executor(Runnable command);
  2. ExecutorService.submit(xxx): 是对Executor接口提交任务的扩充;


  • 方式1:

【并发编程】Executor架构介绍_构造函数_17


  • 方式2:

【并发编程】Executor架构介绍_实现原理_18

【并发编程】Executor架构介绍_实现原理_19

【并发编程】Executor架构介绍_异步任务_20

【并发编程】Executor架构介绍_实现原理_21


ExecutorService接口

【并发编程】Executor架构介绍_异步任务_22

ExecutorService接口是对Executor接口的扩展,主要增加了如下方法:

  1. 生命周期管理方法;
  2. 提交任务的简便方法;

【并发编程】Executor架构介绍_构造函数_23

shutdown()和shutdownNow()比较

  1. shutdown():平缓关闭,不会接收新任务的提交,会等待已提交任务全部执行完;
  2. shutdownNow():粗暴关闭,不会接收新任务的提交,尝试取消正在运行的任务,返回已提交但尚未运行的任务列表;


【并发编程】Executor架构介绍_构造函数_24


【并发编程】Executor架构介绍_异步任务_25

批量任务:invokeAll()/invokeAny()


方法说明

【并发编程】Executor架构介绍_构造函数_26


【并发编程】Executor架构介绍_构造函数_27


【并发编程】Executor架构介绍_异步任务_28


【并发编程】Executor架构介绍_异步任务_29

invokeAll()实现原理

【并发编程】Executor架构介绍_构造函数_30



CompletionService接口

具体实现类: ExecutorCompletionService


  • 用于提交批量异步任务,并获取结果;
  • 用于将批量异步任务的生产和消费进行解耦;


方法介绍


【并发编程】Executor架构介绍_实现原理_31

使用示例

【并发编程】Executor架构介绍_实现原理_32

实现原理

  • Executor: ExecutorCompletionService委托Executor来执行任务提交操作;
  • BlockingQueue: 委托BlockingQueue来保存计算结果;

【并发编程】Executor架构介绍_构造函数_33


【并发编程】Executor架构介绍_异步任务_34


【并发编程】Executor架构介绍_实现原理_35


步骤1:提交任务

  1. 将提交的任务封装为QueueingFuture;
  2. 委托Executor进行任务提交;

【并发编程】Executor架构介绍_构造函数_36


步骤2: 重写done()方法

  1. 重写FutureTask的done()方法,当Future任务执行完成后,调用done(),将Future任务添加到BlockingQueue中;

【并发编程】Executor架构介绍_实现原理_37


步骤3:

  1. 委托BlockingQueue实现获取任务的同步;

【并发编程】Executor架构介绍_异步任务_38

CompletionService接口和ExecutorService.invokeAll()比较

相同点:

都可以进行批量任务提交与处理;


不同点:

ExecutorService.invokeAll():


  1. 每次提交1组任务,返回时,也是返回1组任务(Future);
  2. 必须等待所有任务执行完,才会返回结果,返回的任务列表与提交的任务列表顺序相同


CompletionService接口:


  1. 每次提交1个任务,任务执行完成后,会将任务放到BlockingQueue中;
  2. BlockingQueue中存放的任务顺序,与提交的任务顺序很可能不同,哪个任务先执行完,就先放入哪个任务;
  3. 不必等待所有任务执行完;




























【并发编程】Executor架构介绍_异步任务_39


配置ThreadPoolExecutor


【并发编程】Executor架构介绍_异步任务_40


【并发编程】Executor架构介绍_实现原理_41


【并发编程】Executor架构介绍_异步任务_42


【并发编程】Executor架构介绍_实现原理_43






























举报

相关推荐

0 条评论