05任务执行

任务执行

“任务执行”的意义?

  1. 简化程序的组织结构
  2. 提供一种自然的事物边界来优化错误恢复过程
  3. 提供一种自然的并行结构来提升并发性

在线程中执行任务

如何找出清晰的任务边界?

理想情况下,任务并不依赖其它任务的状态、结果和边界效应

串行的执行任务

串行执行的问题?

性能差,在等待IO时,CPU空闲

响应性和吞吐量查

基于 线程串行 的 Web 案例 :

image-20200812191922950

显式的为任务创建线程

基于 线程并行 的 Web 案例 :

image-20200812192051959

有哪些特点?

  1. 接受用户请求速度加快
  2. 请求并发执行
  3. 任务处理代码必须是现行安全的

无限创建线程会有哪些问题?

  1. 线程生命周期的开销非常高:线程的创建,切换,消耗等
  2. 资源消耗 :活跃的线程会消耗系统资源 , 尤其是内存 。大量的闲置线程会导致GC频繁。
  3. 稳定性:可创建的线程数量存在限制.,超出闲置报OOM错误

Executor 框架

和quene对比?

基于quene,但是简化了线程的管理工作,使用上更加灵活

Executor 框架 有哪些优点?

  1. 任务提交和任务执行解耦,支持各种执行策略(包含了上面的串行和并行)
  2. 提供对生命周期的支持,统计信息收集, 应用程序管理机制, 性能监视机制

基于 Executor 的 Web 案例 :

image-20200812193459306

执行策略

有哪些执行策略?

  • 在什么线程中执行任务
  • 按照什么顺序执行(FIFO , LIFO , 优先级)
  • 有多少个任务可以并发执行
  • 队列中有多少个任务在等待执行
  • 需要拒绝任务时如何选择 , 并进行通知
  • 执行任务前后应该进行哪些动作

线程池

管理一组同构(多个相同类型的物体参与完成某一件事情)工作线程的资源池

Executor 生命周期

ExecutorService 扩展 Executor 为提供生命中期的管理:运行、关闭、终止

image-20200812194111376

创建后就处于运行状态

关闭方式:

  • shutDown : 执行平缓的关闭过程 : 不再接受新的任务 , 同时等待提交的任务执行完成.
  • shutDownNow : 取消所有运行的任务 , 并不再启动尚未执行的任务

    所有任务完成后 ExecutorService 转入终止状态

ThreadPoolExecutor生命周期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>   * The runState provides the main lifecycle control, taking on values:
> *
> * RUNNING: Accept new tasks and process queued tasks
> * SHUTDOWN: Don't accept new tasks, but process queued tasks
> * STOP: Don't accept new tasks, don't process queued tasks,
> * and interrupt in-progress tasks
> * TIDYING: All tasks have terminated, workerCount is zero,
> * the thread transitioning to state TIDYING
> * will run the terminated() hook method
> * TERMINATED: terminated() has completed
> *
> * The numerical order among these values matters, to allow
> * ordered comparisons. The runState monotonically increases over
> * time, but need not hit each state. The transitions are:
> *
> * RUNNING -> SHUTDOWN
> * On invocation of shutdown(), perhaps implicitly in finalize()
> * (RUNNING or SHUTDOWN) -> STOP
> * On invocation of shutdownNow()
> * SHUTDOWN -> TIDYING
> * When both queue and pool are empty
> * STOP -> TIDYING
> * When pool is empty
> * TIDYING -> TERMINATED
> * When the terminated() hook method has completed
>

延迟性任务和周期任务

Timer 的不足?

  1. 基于绝对时间的调度机制:通过修改系统的时间就可以影响任务的执行时间
  2. 执行所有的定时任务时只会创建一个线程. 如果某个任务执行时间过长将会破坏其他任务的定时准确性
  3. Timer的执行任务的线程不会捕获异常, 如果 timerTask 抛出异常, 将会终止 Timer 的线程.(线程泄露)

ScheduledThreadPoolExecutor 可以很好的代替 Timer

找出可利用的并行性

案例情形:串行地渲染页面元素

问题一:串行没有充分利用CPU,性能较差,大部分时间都用于IO,用户需要等待时间较长。

image-20200812194834276

优化一:将渲染过程分解为两个任务并发执行,因为有返回,可以使用 Callable 和 Future

image-20200812194940655

Future 和 FutureTask 的区别?

Future 表示 任务Runnable 的生命周期

FutureTask 实现了 Future 和 Runable 接口,是一个能管理自身生命周期的可执行任务

问题二:并行的处理下载图片和渲染文本,但是两者耗时不一致,必须在等待所有的图片都下载完后再进行显示。这就是在异构任务并行化的局限性:异构的任务执行时间不一致,并行的结果取决于耗时最长的任务。

线程生命周期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>   //FutureTask
> /**
> * The run state of this task, initially NEW. The run state
> * transitions to a terminal state only in methods set,
> * setException, and cancel. During completion, state may take on
> * transient values of COMPLETING (while outcome is being set) or
> * INTERRUPTING (only while interrupting the runner to satisfy a
> * cancel(true)). Transitions from these intermediate to final
> * states use cheaper ordered/lazy writes because values are unique
> * and cannot be further modified.
> *
> * Possible state transitions:
> * NEW -> COMPLETING -> NORMAL
> * NEW -> COMPLETING -> EXCEPTIONAL
> * NEW -> CANCELLED
> * NEW -> INTERRUPTING -> INTERRUPTED
> */
> private volatile int state;
> private static final int NEW = 0;
> private static final int COMPLETING = 1;
> private static final int NORMAL = 2;
> private static final int EXCEPTIONAL = 3;
> private static final int CANCELLED = 4;
> private static final int INTERRUPTING = 5;
> private static final int INTERRUPTED = 6;
>

何为异构任务?

结构不同的任务,也可以理解为两个独立的且逻辑不一样的过程。

优化二:并发的处理大量独立且同构的任务

image-20200812195121513

CompletionService 介绍:

  • 使用指定的 Execotor 执行计算任务
  • 使用 BlockingQueue 保存计算结果

为什么不使用 ExecutorService 结合 Future?

参考https://www.cnblogs.com/hapjin/p/10898451.html

java8 CompletableFuture更牛批:

  1. 实现了异步回调(取代了Future.get()的阻塞方式)
  2. 任务执行流程控制(可以灵活的控制任务执行的流程)

本文标题:05任务执行

文章作者:Sun

发布时间:2020年08月12日 - 20:08

最后更新:2020年08月24日 - 10:08

原始链接:https://sunyi720.github.io/2020/08/12/Java并发编程/05任务执行/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。