Executor框架

Executor框架

Executor框架的两级模型

java的线程被一对一映射为本地操作系统的线程。
当java线程启动时,会创建一个本地操作系统的线程,当该java线程终止时,本地操作系统的进程也会被回收。
操作系统调度所有的线程并将他们分配给可用的CPU。

上层:java多线程程序将应用分解成多个任务,然后由用户级的调度器Executor框架将这些任务映射为固定数量的线程
下层:由操作系统的内核将这些线程映射到硬件处理器上。
两级模型

Executor框架的结构

  1. 任务:包括被执行任务需要实现的接口:Runnable和Callable
  2. 执行:任务执行的核心接口Executor,以及继承自Executor的ExecutorService接口。Executor有两个关键类实现了ExecutorService接口:
    • ThreadPoolExecutor线程池的核心实现类,用来执行提交的任务。
    • ScheduledThreadPoolExecutor:可以在给定的延迟后运行命令,或者定期执行命令。
  3. 异步计算的结果:包含Future接口和实现了Future接口的FutureTask类。
    Executor框架的执行过程:
    1. 首先,主线程创建Runnable或者Callable接口的对象。(Executors工具类可以将Runnable对象封装成一个Callable对象:Executors.callable(Runnable task) 或者
      Executors.callable(Runnable task, Object resule))
    2. 然后,将Runnable对象直接交给ExecutorService执行:ExecutorService.submit(Runnable command); 或者将Runnable或者Callable对象利用ExecutorService.submit(Runnable/Callable task)。
    3. 如果执行的是submit()方法,将返回一个实现了Future接口的对象或者FutureTask类。因为FutureTask类也实现了Runnable接口,因此也可以直接提交FutureTask去执行。
    4. 主线程可以调用FutureTask.get()来等待任务的执行,此方法会阻塞主线程;也可以调用FutureTask.cancel(boolean mayInterruptIfRunning)来取消任务的执行。

Executor框架的成员

ThreadPoolExecutor

线程池,通常使用工厂类Executors创建。
  1. 单个线程的线程池:适用于需要保证线程的顺序执行,并且在任意时间不会有多个线程是活动的应用场景。
    ExecutorService c = Executors.newSingleThreadExecutor();
  2. 固定数量的线程池,为了满足资源管理的需求,适用于负载比较重的服务器:
    ExecutorService c = Executors.newFixedThreadPool(20);
  3. 缓冲线程池:根据需要创建线程的无界的线程池。适用于执行很多的短期异步的小程序或者负载比较轻的服务器。
    ExecutorService c = Executors.newCachedThreadPool();

ScheduledThreadPoolExecutor

继承自ThreadPoolExecutor,同时实现了ScheduledExecutorService接口。
ScheduledExecutorService接口定义了ScheduledThreadPoolExecutor能够延时执行任务和周期执行任务的功能;
Timer是单个后台线程的定时器,而ScheduledThreadPoolExecutor对应的是多个后台线程。
  1. 利用的DelayQueue(延迟阻塞无界队列)存储ScheduledFutureTask来实现的。
    ScheduledFutureTask任务具有:定时时间、加入队列的序号以及任务的执行间隔周期等属性。
    DelayQueue首先根据time排序,即时间早的任务在前面;如果时间相同,就根据加入队列的顺序即序号来排序。
  2. 使用Executors工具类来创建:
    1. 创建固定线程数的线程池:适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而控制后台线程的数量。
      ExecutorService c = Executors.newScheduledThreadPool(20);
    2. 创建单线程的线程池:需要单个线程后台执行周期任务,同时需要保证任务执行的顺序。
      ExecutorService c = Executors.newSingleThreadScheduledExecutor();

Future接口

调用submit()方法返回的异步计算的结果:Future接口或者实现了Future接口的FutureTask类。
目前为止,异步处理结果返回的都是FutureTask类对象
  • FutureTask类
    • 实现了Runnable、Future接口
    • 可以被Executor执行,也可以直接调用run()方法执行
    • 基于AQS实现的,AQS是一个用来构建锁和其他同步组件的框架。提供通信机制用来原子性管理同步状态、阻塞和唤醒线程。

Runnable接口和Callable接口

Runnable接口不会返回结果,而Callable接口会返回结果。
但是可以利用工具类Executors将一个Runnable接口通过调用callable(Runnable task)封装成Callable接口。
©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页