大多数的应用程序都是围绕“任务执行”来构造的:任务常常是一些抽象的并且离散的工作单元。我们把应用程序的工作分解到多个任务中,可以简化程序的组织结构,提供一种自然的事物便捷来优化错误恢复过程,并且提供一种自然的并行结构来提升并发性。
在线程中执行任务
我们在围绕任务执行来设计程序结构的时候,首先就是要找出清晰的任务边界,一般来说,任务之间是相互独立的---任务不依赖其他任务。独立性有助于实现并发。大多数的服务器应用程序都提供了一种自然的任务边界选择方式:以独立的客户请求为边界。
串行地执行任务
显示的为任务创建线程
无线创建线程的不足:现成的生命周期开销非常高;资源消耗;稳定性。
Executor框架
在Java类库中,任务执行的主要抽象不是Thread,而是Executor,虽然Executor是个简单的接口,但它却为灵活且强大的异步任务执行框架提供了基础。它提供了一种标准的方法将任务的提交过程与执行过程解耦开来,并用Runnable来表示任务。Executor的实现还提供了对生命周期的支持、统计信息收集、应用程序管理机制和性能监视等机制。它基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程相当于消费者。
void execute(Runnable command)
在未来某个时间执行给定的命令。该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由 Executor 实现决定。
参数:
command - 可运行的任务
抛出:
RejectedExecutionException - 如果不能接受执行此任务。
NullPointerException - 如果命令为 null
线程池
线程池就是管理一组同构工作线程的资源池。线程池是与工作队列密切相关的,其中在工作队列中保存了所有等待执行的任务。工作者线程的任务就是从工作队列中取出一个任务执行完毕之后再返回线程池等待下个任务。
在线程池中执行任务比为每个任务分配一个线程优势更大。我们可以通过调用Executors中的静态工厂方法来创建一个线程池。
Executor的生命周期
如何关闭一个Executor呢?Executor的实现通常会创建线程来执行任务,但是JVM只有在所有的非守护线程结束后才会退出,所以如果没有正确的关闭Executor,JVM将无法结束。为了解决执行服务的生命周期问题,Executor拓展了ExecutorService接口,添加了生命周期管理的方法。