并发编程-20 Executor框架

版权声明:【show me the code ,change the world】 https://blog.csdn.net/yangshangwei/article/details/88083560

概况

我们使用线程来异步执行任务。众所周知,Java线程的创建与销毁需要一定的开销,如果为每一个任务创建一个新线程来执行,势必将消耗大量的计算资源。 Java的线程既是工作单元,也是执行机制。

从JDK 5开始,把工作单元与执行机制分离开 来。工作单元包括Runnable和Callable,而执行机制由Executor框架提供。


Executor框架的两级调度模型

在HotSpot VM的线程模型中,Java线程(java.lang.Thread)被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当该Java线程终止时,这个操作系统线程也会被回收。操作系统会调度所有线程并将它们分配给可用的CPU。

  • 在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定数量的线程

  • 在底层,操作系统内核将这些线程映射到硬件处理器上。

这种两级调度模型的示意图如下
在这里插入图片描述
从上图中可以看出,应用程序通过Executor框架控制上层的调度;而下层的调度由操作系统内核控制,下层的调度不受应用程序的控制。


Executor框架的3大组成部分

在这里插入图片描述

  • 任务:包括被执行任务需要实现的接口:Runnable接口或Callable接口

  • 任务的执行: 包括任务执行机制的核心接口Executor,以及继承自Executor的 ExecutorService接口。Executor框架有两个关键类实现了ExecutorService接口:ThreadPoolExecutorScheduledThreadPoolExecutor

    扫描二维码关注公众号,回复: 5390842 查看本文章
  • 异步计算的结果: Future接口和实现Future接口的FutureTask类


Executor框架的主要接口和类

在这里插入图片描述

  • Executor:接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来。

  • ExecutorService:是一个比Executor使用更广泛的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法

  • AbstractExecutorService:ExecutorService执行方法的默认实现

  • ScheduledExecutorService:一个可定时调度任务的接口

  • ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池

  • ThreadPoolExecutor:线程池的核心实现类,用来执行被提交的任务


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(Callable<T>task)

如果执行ExecutorService.submit(…),ExecutorService将返回一个实现Future接口的FutureTask对象。 由于FutureTask实现了Runnable,也可以创建FutureTask,然后直接交给ExecutorService执行。

最后,主线程可以执行FutureTask.get()方法来等待任务执行完成。主线程也可以执行FutureTask.cancel(boolean mayInterruptIfRunning)来取消此任务的执行。


Executor框架的成员详解

主要介绍Executor框架的主要成员:ThreadPoolExecutorScheduledThreadPoolExecutor
Future接口、Runnable接口、Callable接口和Executors


ThreadPoolExecutor

ThreadPoolExecutor通常使用工厂类Executors来创建。

Executors可以创建3种类型的ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool、CachedThreadPool


FixedThreadPool

创建使用固定线程数的线程池

FixedThreadPool适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器

使用示例: https://artisan.blog.csdn.net/article/details/77765659#newFixedThreadPool_412


SingleThreadExecutor

创建使用单个线程,SingleThreadExecutor适用于需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。

使用示例:https://artisan.blog.csdn.net/article/details/77765659#newSingleThreadExecutor_524


CachedThreadPool

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

使用示例:https://artisan.blog.csdn.net/article/details/77765659#newCachedThreadPool_625


ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor通常使用工厂类Executors来创建。Executors可以创建2种类型的ScheduledThreadPoolExecutor: ScheduledThreadPoolExecutor、SingleThreadScheduledExecutor

  • ScheduledThreadPoolExecutor:
    包含若干个线程的ScheduledThreadPoolExecutor
  • SingleThreadScheduledExecutor:只包含一个线程的ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor

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

使用示例:https://artisan.blog.csdn.net/article/details/77765659#newScheduledThreadPool_849


SingleThreadScheduledExecutor

SingleThreadScheduledExecutor适用于需要单个后台线程执行周期任务,同时需要保证顺序地执行各个任务的应用场景

使用示例:https://artisan.blog.csdn.net/article/details/77765659#newSingleThreadScheduledExecutor_761


Future接口

Future接口和实现Future接口的FutureTask类用来表示异步计算的结果。当我们把Runnable接口或Callable接口的实现类提交(submit)给ThreadPoolExecutorScheduledThreadPoolExecutor时,ThreadPoolExecutorScheduledThreadPoolExecutor会返回一个FutureTask对象.

API:

<T> Future<T> submit(Callable<T> task)
<T> Future<T> submit(Runnable task, T result)
Future<> submit(Runnable task)

Runnable接口和Callable接口

Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutorScheduledThreadPoolExecutor执行。它们之间的区别是Runnable不会返回结果,而Callable可以返回结果.


猜你喜欢

转载自blog.csdn.net/yangshangwei/article/details/88083560
今日推荐