Executor

Executor

在 Java 类库中,任务执行的主要抽象不是 Thread,而是 Executor。虽然 Executor 只是一个简单的接口,但却为 JDK 中灵活且强大的异步任务执行框架提供了基础。

异步任务执行框架

使用 Runnable 表示任务,能支持多种任务执行策略,且提供了一种标准方法将任务的提交和执行解耦。此外,Executor 的实现还提供了对生命周期的支持,以及统计信息收集、应用程序管理机制和性能监视等机制。

Executor 基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程则相当于消费者。要用 Java 实现一个生产者-消费者的设计,最简单可靠的方式就是使用 Executor。

Executor 的优势:

通过将任务的提交和执行解耦开来,从而可以很方便的为某种类型的任务指定和修改执行策略。所谓任务的执行策略包括:

  1. 在什么线程中执行任务?
  2. 任务按照什么顺序执行(FIFO、LIFO、优先级)?
  3. 有多少个任务可以并发执行?
  4. 在队列中有多少个任务在等待执行?
  5. 如果系统因为过载而需要拒绝一个任务,应该选择哪一个任务?另外,如何通知应用程序有任务被拒绝?
  6. 在执行一个任务之前或之后,应该进行哪些动作?

任务执行策略可以理解为一种资源管理工具,最佳策略取决于可用的计算资源以及对服务质量的需求。

通过限制并发任务的数量,可以确保应用程序不会由于资源耗尽而失败,或者由于在稀缺资源上发生竞争而严重影响性能。

通过将任务的提交和任务的执行策略分离开来,有助于在部署阶段选择与可用硬件资源最匹配的执行策略。

Executor 生命周期:

关闭 Executor: Executor 的实现通常会创建线程来执行任务,而 JVM 只有在所有(非守护)线程全部终止后才会退出。因此,如果无法正确的关闭 Executor,那么 JVM 则无法正常退出。

ExecutorService: ExecutorService 扩展了 ExecutorService 接口,添加了一些管理生命周期的方法。ExecutorService 的生命周期有3种状态:运行关闭终止

在刚被创建时 ExecutorService 处于初始状态

调用 shutdown 方法或 shutdownNow 方法将使 ExecutorService 处于关闭状态

shutdown 方法 的关闭过程较平缓,执行 shutdown 后 Executor 不会再接受新的任务,同时等待已经提交的任务执行完成。

shutdownNow 方法 的关闭过程则十分粗暴,它将尝试取消所有运行中的任务,并且不再启动队列中尚未开始执行的任务。

ExecutorService 处于关闭状态后提交的任务将由 “拒绝执行处理器(Rejected Execution Handler)”来处理,它会抛弃任务或者使得 execute 方法抛出一个未检查的 RejectedExecutionException。

所有任务都执行结束或被强制关闭后,ExecutorService 进入终止状态。可以调用 awaitTermination 方法等待 ExecutorService 进入终止状态,也可以调用 isTerminated 方法轮询其是否终止。

线程池

线程池是管理一组同构工作线程的资源池,和工作队列密切相关。工作线程从工作队列中获取一个任务并执行,执行完后返回线程池并等待下一个任务。

线程池可以重用现有的线程而不是为每个任务创建新的线程,这样便能避免线程创建和销毁过程中产生的巨大开销。此外,由于请求到达时线程已经存在,因此无需等待线程创建而延迟任务的执行,从而提高响应性。

通过调整线程池的大小,可以使得线程数量恰好保证CPU处于忙碌状态的同时避免过多线程竞争资源而降低性能。

Executors 中有创建各种线程池的静态工厂方法。

  1. newFixedThreadPool
    创建一个固定长度的线程池,一开始每当提交一个任务时就创建一个线程,直到达到线程池允许的最大线程数量,此时线程池的规模将不再变化。(若某个线程发生了未预期的 Exception 而结束,那么线程池会补充一个新的线程)。
  2. newCachedThreadPool
    创建一个可缓存的线程池,如果当前线程池的规模超过了处理需求时,那么将回收空闲的线程,而当需求增加时,则再添加新的线程,线程池的规模不存在任何限制。
  3. newSingleThreadExecutor
    创建单个工作者线程来执行任务,如果这个线程异常结束,会创建一个新的线程来代替。它能确保依照任务在队列中的顺序串行执行(如 FIFO、LIFO、优先级)。
  4. newScheduledThreadPool
    创建一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于 Timer。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值