java并发实战第六章

来源:互联网 发布:淘宝商店转让 编辑:程序博客网 时间:2024/06/16 12:31

最近在看深入理解java虚拟机与java并发实战两本书感觉作者写的还是很好的,奈何水平有限,所以打算继续研究并做好笔记进行总结

第六章围绕任务执行来讲述的,通常应用程序把工作分解到多个任务中,这样可以简化程序的组织结构,并提高程序的并发性,围绕任务执行应该先找到清晰地任务边界,理想情况下,各任务之间应该不相互依赖,正常负载下,应用程序应该具有良好的响应性和吞吐量。因此在构造任务策略的时候应尽可能的围绕这两点进行。

串行执行任务

一般情况下,最简单的任务执行策略是串行的执行各任务,但是这种执行效率很低,这种执行方式一般对cpu等资源的利用率非常低,因而无法提供较高的吞吐量。

为每个任务显式的创建线程

①优点:

显式的为每个任务创建线程可以实现更高的响应性,解决了串行任务资源利用率低的问题,利用此方法将任务处理过程从主线程分离出来。

②缺点

线程生命周期开销非常高,系统在创建和销毁线程时都会有非常大的开销,线程在运行的过程中也会消耗系统资源,如果线程数多余处理器处理数大量的线程会被闲置从而占用更多的内存资源,因而创建的线程以保证处理器足够忙碌为宜不应过多也不应过少,过多的线程线程会抛出outofMemoryError异常从而影响应用程序的稳定性

2.Executor框架

线程池

为了解决上述两种执行任务的缺点,通常使用线程池来简化线程池的管理工作,线程池是管理一组同构线程(多个相同类型的参与完成某一件任务的线程)的一个资源池,java类库提供了一个灵活的线程池和一些有用的配置,通常可以创建的线程池有以下几类:

newFixedThreadPool:创建一个固定长度的线程池,每次提交一个任务就创建一个线程,直到达到线程池的上限

newCachedThreadPool:创建一个可缓存的线程池,当请求任务过小,回收空闲的线程,任务过大增加线程数量

newSingleThreadPool:创建单个工作者线程池

newScheduledThreadPool:创建一个固定任务,并可以延时或定时执行任务的线程池。

Executor框架

在java并法包中提供了灵活的线程池实现作为Executor框架的一部分。Executor框架通常实现Executor接口,Executor框架可以支持多种任务执行策略,有效的任务的提交与执行解耦开Executor一般基于生产者消费者模式提交的任务相当于生产者,执行的任务相当与消费者,通常Executor使用runnable作为基本的任务表示形式但是Runnable任务没有返回值或者抛出一个受检查异常,用Callable通常可以解决这类问题。Executor框架中Future表示一个任务的生命周期,并提供了相应方法判断任务是否已经完成或取消,Future通常用get方法来获取任务的执行状态。Executor框架中如果提交了一组计算任务并且希望得到计算结果,那么可以保留每个任务的Future,然后反复执行get方法,但是这种方法太繁琐,通常使用CompletionService,完成服务将Executor框架和阻塞队列的功能融合在一起,从而可以将任务提交到一个队列并用take或poll方法得到结果。但是有些任务无法再指定时间内完成因而可以为线程指定时限,任务超时后抛出超时异常并终止,注意在这种情况下任务应该立即终止,避免任务执行过长浪费更多的资源。

Exector生命周期

Executor扩展了ExecutorService接口从而解决服务的生命周期问题,一般ExecutorService提供的生命状态有三种包括运行关闭和终止

延迟任务与周期任务

延迟任务和周期任务一般由Timer类管理,但是此类存在一些缺陷他只会为所有定时的任务创建一个线程并且TimerTask会抛出一个未检查异常因此可以考虑使用ScheduledThreadExecutor代替。

原创粉丝点击