Executor框架简介

来源:互联网 发布:plc网络名称 编辑:程序博客网 时间:2024/06/16 15:00

注:本文为《java并发编程的艺术》学习笔记,详情请参考书籍。

引言:

我们知道,线程的创建和销毁需要一定的开销,大量频繁的创建线程将给系统带来很大的负荷。

从JDK5开始,Java就将线程的工作单元和执行机制分开。

工作单元包括:Runnable和Callable;

执行机制包括Executor框架。

Executor框架的两级调度模型:

在HotSpot VM的线程模型中,Java线程被一对一的映射为本地OS线程。OS会调度所有线程并将它们分配给可用的CPU。

1、在上层,应用程序通过Executor框架控制上层的调度,将这些任务映射为固定数量的线程;

2、在下层,由OS内核控制,下层调度不受应用程序控制。

Executor框架结构:

1、Executor框架主要有3大部分组成:

(1)任务:包括被执行任务需要实现的接口,Runnable接口或Callable接口。

(2)任务的执行:包括任务执行机制的核心接口Executor,以及继承自Executor接口的ExecutorService接口。

ExecutorService接口有两个关键类实现了它:ThreadPoolExecutor和ScheduledThreadPoolExecutor。

(3)异步计算的结果:包括接口Future和实现该接口的FutureTask类。

Executor框架执行过程:

1、主线程首先创建实现Runnable接口或Callable接口的任务对象;工具类通过Executors.callable(Runnable task)可以将一个Runnable对象封装为一个Callable对象;

2、把Runnable对象直接交给ExecutorService执行,采用方法ExecutorService.execute(Runnable command);或使用Callable对象,方法为ExecutorService.submit(Callable<T> task)。

3、上述submit方法将返回一个实现Future接口的对象(目前的JDK是FutureTask对象)。由于FutureTask实现了Runnable,我们也可以将FutureTask交给Runnable执行。

4、主线程执行FutureTask.get()来等待任务执行完成,也可以使用cancel来取消任务执行。

Executor框架的成员:

1、ThreadPoolExecutor:使用Executors创建,共有三种类型:SingleThreadExecutor(单线程、保证顺序)、FixedThreadPool(适合负载比较重的服务器)、CachedThreadPool(大小无界的线程池,适合执行很多短期异步任务的小程序,负载较轻的服务器)。这几个方法均是静态方法。

它们对应的API就是在名字前面加上new。

2、ScheduledThreadPoolExecutor:分为若干个和单个两种类型。

它适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。

而SingleThreadScheduledExecutor适合于单个后台线程执行周期任务,同时保证执行顺序。

3、Future接口:

Future接口和实现它的FutureTask类用来表示异步计算的结果。

当我们把实现Callable接口或Runnable接口的类放进ExecutorService中执行时,会返回一个FutureTask对象。(目前只有FutureTask对象实现了Future接口,实际是返回Future接口的泛型类,因此以后API可能会改变)。

4、Runnable接口和Callable接口:

实现它们的类对象都可以被ThreadPoolExecutor执行,不同的是Runnable接口不会返回值,而Callable接口会返回结果。

因此我们可以采用工厂类Executors将Runnable接口包装成Callable。

Future.Task.get()可以用来等待任务执行完成,并返回结果。