首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

并发编程实战-第6章

序文:

如果你没有时间阅读这本,那你就来对地方了。小编会将每一章刨去废话,取其精华。分享给大家。如果觉得可以请不要忘了关注小编。我会定期跟新java 中的经典书籍。

正文:

第6章:任务执行(Executor)

1.任务执行:抽象的离散的工作单元,将程序的工作分解到多个任务中,可以简化程序的组织结构来提升并发性。

2.独立任务:任务不依赖于其他任务的状态、结果或者边界效应。(没有共享资源)

3.服务器负荷过载,应用程序应该是逐渐降低效率,而不是直接失败。

4.大多数的服务器应用程序都以独立的客户请求作为边界。(一个请求一个线程,web服务等)

5.并行相对的执行方式就是串行,串行执行通常无法提高吞吐率或快速响应。

6.在正常负载的情况下,“为每个任务分配一个线程”的方法能提升串行执行的性能。(前提条件就是正常负载,不超过服务器的请求处理能力。即使这样也不推荐这么用,如果任务过多,或者恶意的请求都可能使程序因为创建大量线程占用内存,导致线程泄露,内存逸出)

7.不要无限制的创建线程:

线程创建和销毁将消耗大量的资源。

活跃的线程会消耗系统资源,尤其是内存。

如果线程数量超过处理器的数量,那么大量线程是无法及时执行的,闲置的线程任然占用内存,这样会时性能大打折扣。

8.串行执行的问题在于糟糕的响应和吞吐率,为每个任务分配线程的问题在于资源管理复杂性。

9.Executor(接口)框架:

java 类库中主要的任务执行抽象 是Executor不是Thread.

提供一种标准的方法将任务的提交过程和执行过程解耦开来。

Runnable、Callable来表示任务

提供了对生命周期的支持,以及统计信息收集,性能监控等机制

基于 生成者-消费者模式(提交任务 生产,执行任务 消费)

10.线程池(可以理解为一个管理线程的资源管理器)

可以避免每次任务提交都会有创建和销毁线程的开销。(先创建好有任务来分配一个线程)

创建线程池(使用Executor静态工程来创建):

newFixedThreadPool 固定线程数量,(来一个任务创建一个,直到达到固定的数量)

newCachedTreadPool 根据任务的多少来自动开辟线程,和回收空闲的线程。

newSingleThreadExecutor 单线程(和Thread 的区别就是可以重用,当有新的任务的时候还是可以使用之前创建的线程来执行)

newScheduledThreadPool 类似于 Timer

11.jvm(java 虚拟机)只用在所有的守护线程全部终止以后才会退出。

守护线程就是非主线程

所以要正确的关闭已经创建的线程

12.Executor 异步方式执行任务

所以任务可能处于各种状态(完成,正在运行,取消)

13.ExecutorService 用于管理任务服务的生命周期

3中状态:运行 关闭 已终止

shutdown 平缓的关闭,不在接受新的任务,同时等待已经提交的任务执行完成(队列中的任务会执行完)

shutdownNow 粗暴关闭 尝试取消所有运行中的任务,并且不在启动队列中尚未启动的任务。

awaitTermination 等待所有任务到达终止状态(通常会和shutdown 一起用来产生同步的关闭ExecutorService-第七章会中有介绍)

14.Callable 与 Runnable

Callable和Runnable 比较:

Runnable run方法(入口)没有返回值或者抛出一个受检测异常

Callable call方法(入口)将返回一个返回值或者抛出一个异常

15.Future

用来描述一个任务的生命周期(创建、提交、开始、完成)

常用 判断任务是否取消,获取任务的执行结果

get方法来获取任务的状态。(如果任务完成会立即抛出一个Exception,如果没有完成会阻塞直到完成)

16.如何获取Future

当你使用ExcutorService 来提交任务(submit的时候会返回这个任务的Future)

Future的结果包含了一个安全发布。是安全的发布到任何获取它的线程。

17.只用当大量相互独立且同构的任务可以并发进行处理,才能体现出分配任务带来的性能提升。(例如两个任务一个毫秒级别,一个大量的计算,这样和串行执行对比不能显示出优势)

18.CompletionSerivce :将先完成的任务放到队列中调用take 方法获取Future.

这个适用于 网页中的图片加载,加载好一张显示一张。

19.设置任务的时限

一个任务不能长时间占用线程,超时后应该立即停止,释放资源。

所以要设置一个时间限制,超时返回默认的值或做一些处理。

通过get(时间,时间类型) 超时抛出TimeOutExecption

20.Runable提交因为没有返回值 所以Future 获取的是null,Callable根据自己的call返回值Future返回对应call 的返回值。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190210A0EI3Y00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券