Exector框架主要由三大部分组成如下:
任务,包括被执行任务需要实现的接口:Runnable接口或Callable接口
任务的执行,包括任务执行机制的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduleThreadPoolExecutor)。
异步计算的结果,包括接口Future和实现Future接口的FutureTask类。
Executor框架的成员
1.Executor是一个接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来。
2.ThreadPoolExecutor是线程池的核心实现类,用来执行被提交的任务。
具体api可以参考blog.csdn.net/tongdanping…
3.ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。
具体api可以参考blog.csdn.net/tongdanping…
4.Future接口和实现Future接口的FutureTask类,代表异步计算的结果。
具体api可以参考blog.csdn.net/tongdanping…
5.Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor或ScheduleThreadPoolExecutor执行。
Executor框架使用示意图:
主线程首先要创建实现Runnable或者Callable接口的任务对象。 工具类Executors可以把一个Runnable对象封装为一个Callable对象:Executors.callable(Runnable task)或Executors.callable(Runnable task,Object resule)。
然后可以把Runnable对象直接交给ExecutorService执行ExecutorService.execute(Runnable command);或者也可以把Runnable对象或Callable对象提交给ExecutorService执行ExecutorService.submit(Runnable task或ExecutorService.submit(Callabletask)。
如果执行ExecutorService.submit(...),ExecutorService将返回一个实现Future接口的对象(到目前为止的JDK中,返回的是FutureTask对象)。由于FutureTask实现了Runnable,程序员也可以创建FutureTask,然后直接交给ExecutorService执行(AsyncTask就是这样做的)。
最后,主线程可以执行FutureTask.get()方法来等待任务执行完成。主线程也可以执行FutureTask.cancel(boolean mayInterruptIfRunning)来取消此任务的执行。
execute和submit的区别:
1.可以接受的任务类型不同,execute只能接受Runnable类型的任务;submit不管是Runnable还是Callable类型的任务都可以接受
2.submit()有返回值,而execute()没有
2.submit可以进行Exception处理,submit会吃掉异常,可通过Future的get方法将任务执行时的异常重新抛出;execute会直接抛出任务执行时的异常,可以用try、catch来捕获,和普通线程的处理方式完全一致。
FixedThreadPool代码示例:
当线程池中的线程数大于corePoolSize时,keepAliveTime为多余的空闲线程等待新任务的最长时间,超过这个时间后多余的线程将被终止。这里把keepAliveTime设置为0L,意味着多余的空闲线程会被立即终止。
ExecutorService ftp = Executors.newFixedThreadPool(3);
ftp.execute(runOne);
ftp.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("进入runTwo的线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
ftp.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println("进入runThree的线程");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
两秒后这三个线程同时运行
修改代码: ExecutorService ftp = Executors.newFixedThreadPool(1);
运行后每隔两秒运行一个线程