java多线程---Executor框架

来源:互联网 发布:大唐移动面试知乎 编辑:程序博客网 时间:2024/05/16 14:09

背景:在java中使用线程来执行进行异步任务,线程的创建和销毁需要一定的开销,若为每一个任务创建一个新的线程来执行,这些线程的创建和销毁会消耗大量的计算资源。

Executor框架:将任务映射为固定数量的线程,将工作单元和执行机制分离开来

Executor的结构:

(1)任务:实现Runnable接口或者Callable接口

二者的区别:前者使用run方法,后者使用call方法;前者不可以抛出受检查的异常,后者可以抛出受检查的异常;call方法中可以使用Future来拿到

(2)任务的执行:包括执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。有二个关键类实现了ExecutorService接口,ThreadPoolExecutor和ScheduledThreadPoolExecutor

(3)异步计算执行的结果:接口Future和实现Future接口的FutureTask类(也是唯一的实现类)

执行过程分析:

首先创建Runnable或者Callable接口的任务对象,当然也可以使用工具类将Executors.callable()来将一个Runnable对象转换为一个Callable对象

然后将任务交给ExecutorService去执行,Runnable可以直接交给执行execute()方法执行,也可以提交submit()来执行,而Callable只能submit()执行,submit会返回一个实现Future接口的对象,

最后 使用FutureTask.get()来等待任务执行完成,也可以使用cancel来取消任务的执行


Executor的成员:

(1)ThreadPoolExecutor:使用工厂类Executors的静态方法来创建:有三种类型

FixedThreadPool: 创建固定线程数的线程池,

ExecutorService executorService= Executors.newFixedThreadPool(5);

它主要是在线程池技术中:核心线程池,工作 队列,线程池,这三个中第二步使用了无界的工作队列,因此不会拒绝任务,适用于负载较重的服务器

SingleThreadPool,创建单个线程,保证任务顺序完成,不会有多线程的活动场景,同样使用了无界的工作队列,

ExecutorService executorService= Executors.newSingleThreadExecutor();

前二者都使用了LinkedBlockingQueue队列

CachedThreadPool:是大小无解的线程池,适用于执行很多短期异步任务的小程序,负载较轻的服务器

ExecutorService executorService= Executors.newCachedThreadPool();

会创建新的线程

使用SynchronousQueue队列

(2)ScheduledThreadPoolExecutor

可以使用工具类创建,有二种

ScheduledThreadPoolExecutor,固定线程的

SingleThreadSchduledExecutor,单个线程的

(3)Future

执行单元执行提交方式的Runnable或者Callable会返回一个Future接口的对象

FutureTash实现了Future接口和Runnble接口

有三个状态:

未启动(它的run方法还没有执行之前)

已启动(run方法执行过程中)

前面这二种状态调用FutureTask的get()方法,会导致调用线程阻塞

已完成(执行正常结束或者取消或者异常结束)

这种状态get()会导致调用线程立即返回结果或抛出异常

FutureTask的内部实现也是基于队列同步器来实现的


0 0