您的位置:首页 > 编程语言 > Java开发

Java并发读书学习笔记(五)——任务执行

2018-03-09 22:34 387 查看
大多数并发应用程序都是围绕“任务执行”来构造的:任务通常是一些抽象且离散的工作单元。通过把应用程序的工作分解到多个任务中,可以简化程序的组织结构,提供一种自然的事务边界来优化错误恢复过程,以及提供一种自然的并行工作结构来提升并发性。

5.1 在线程中执行任务

当围绕“任务执行”来设计程序结构时,第一步就是要找出清晰的任务边界。在理想的情况下,各个任务之间是相互独立的:任务并不依赖其他任务的状态、结果或边界效应。独立性有助于实现并发,因为如果存在足够多的处理资源,那么这些独立的任务都可以并行执行。为了在调度和负载均衡等过程中实现更高的灵活性,每项任务还应该表示应用程序的一小部分处理能力。
5.1.1 串行执行任务在应用程序中可以使用多种策略来调度任务,而其中一些策略能更好地利用潜在的并发性。最简单的策略就是在单个线程中串行地执行各项任务。
5.1.2 显式为任务创建线程通过为每个请求创建一个新的线程来提供服务,从而实现更高的响应性。
5.1.3 无限创建线程的不足在生成环境中,为每个任务分配一个线程存在缺陷,尤其是当需要创建大量线程时:线程生命周期的开销非常高,资源消耗,稳定性。

5.2 Executor框架

任务是一组逻辑工作单元,而线程则是使任务异步执行的机制。串行执行的问题在于其糟糕的响应性和吞吐量,而为每个任务分配一个线程的问题在于资源管理的复杂性。
线程池简化了线程管理工作,并且java.util.concurrent提供了一种灵活的线程池实现作为Executor框架的一部分。在Java类库中,任务执行的主要抽象不是Thread,而是Executor。如下:public interface Executor {
void execute(Runnable command);
}虽然Executor是个简单的接口,但它却为灵活且强大的异步任务,执行框架提供了基础,该框架能支持多种不同类型的任务执行策略。它提供了一种标准的方法将任务的提交过程与执行过程解耦,并用Runnable来表示任务。Executor的实现还提供了对生命周期的支持,以及统计信息收集、应用程序管理机制和性能监视等机制。
Executor基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程相当于消费者。如果要在程序中实现生产者-消费者设计,那么最简单的方式通常就是使用Executor。

5.3 找出可利用的并行性

Executor框架帮助指定执行策略,但如果要使用Executor,必须将任务表述为一个Runnable。在大多数服务器应用程序中都存在一个明显的任务边界:单个客户请求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 并发 任务 Executor