Executor框架

概述:java

  • Eexecutor做为灵活且强大的异步执行框架,其支持多种不一样类型的任务执行策略
  • 提供了一种标准的方法将任务的提交过程和执行过程解耦开发
  • 基于生产者-消费者模式,其提交任务的线程至关于生产者,执行任务的线程至关于消费者,并用Runnable来表示任务
  • Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。

Executor的UML图:数组

  • Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),
  • ExecutorService:是一个比Executor使用更普遍的子类接口,其提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行情况返回Future的方法
  • AbstractExecutorService:ExecutorService执行方法的默认实现
  • ScheduledExecutorService:一个可定时调度任务的接口
  • ScheduledThreadPoolExecutor:ScheduledExecutorService的实现,一个可定时调度任务的线程池
  • ThreadPoolExecutor:线程池,能够经过调用Executors如下静态工厂方法来建立线程池并返回一个ExecutorService对象

阿里发布的 Java开发手册中强制线程池不容许使用 Executors 去建立,而是经过 ThreadPoolExecutor 的方式,这样的处理方式让写的同窗更加明确线程池的运行规则,规避资源耗尽的风险缓存

参数说明:框架

  • corePoolSize:核心线程数,若是运行的线程少于corePoolSize,则建立新线程来执行新任务,即便线程池中的其余线程是空闲的
  • maximumPoolSize:最大线程数,可容许建立的线程数,corePoolSize和maximumPoolSize设置的边界自动调整池大小:
  • corePoolSize <运行的线程数< maximumPoolSize:仅当队列满时才建立新线程
  • corePoolSize=运行的线程数= maximumPoolSize:建立固定大小的线程池
  • keepAliveTime:若是线程数多于corePoolSize,则这些多余的线程的空闲时间超过keepAliveTime时将被终止
  • unit:keepAliveTime参数的时间单位
  •  workQueue:保存任务的阻塞队列,与线程池的大小有关:
  •   当运行的线程数少于corePoolSize时,在有新任务时直接建立新线程来执行任务而无需再进队列
  •   当运行的线程数等于或多于corePoolSize,在有新任务添加时则选加入队列,不直接建立线程
  •   当队列满时,在有新任务时就建立新线程
  • threadFactory:使用ThreadFactory建立新线程,默认使用defaultThreadFactory建立线程
  • handle:定义处理被拒绝任务的策略,默认使用ThreadPoolExecutor.AbortPolicy,任务被拒绝时将抛出RejectExecutorException

newFixedThreadPool异步

  • 建立可重用且固定线程数的线程池,若是线程池中的全部线程都处于活动状态,此时再提交任务就在队列中等待,直到有可用线程
  • 若是线程池中的某个线程因为异常而结束时,线程池就会再补充一条新线程

newSingleThreadExecutor性能

  • 建立一个单线程的Executor,若是该线程由于异常而结束就新建一条线程来继续执行后续的任务

newScheduledThreadPoolspa

  • 建立一个可延迟执行或按期执行的线程池
  • 使用newScheduledThreadPool来模拟心跳机制

newCachedThreadPool线程

  • 建立可缓存的线程池,若是线程池中的线程在60秒未被使用就将被移除
  • 在执行新的任务时,当线程池中有以前建立的可用线程就重用可用线程,不然就新建一条线程

Executor的生命周期rest

  • ExecutorService提供了管理Eecutor生命周期的方法
  • ExecutorService的生命周期包括了:运行  关闭和终止三种状态
  • ExecutorService在初始化建立时处于运行状态。对象

    shutdown方法等待提交的任务执行完成并再也不接受新任务,在完成所有提交的任务后关闭

    shutdownNow方法将强制终止全部运行中的任务并再也不容许提交新任务

ExecutorCompletionService

  • 实现了CompletionService,将执行完成的任务放到阻塞队列中,经过take或poll方法来得到执行结果

  • 输出结果:

关注点1 :线程池大小

  • 线程池有两个线程数的设置,一个为核心池线程数,一个为最大线程数。
  • 在建立了线程池后,默认状况下,线程池中并无任何线程,等到有任务来才建立线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法
  • 当建立的线程数等于 corePoolSize 时,会加入设置的阻塞队列。当队列满时,会建立线程执行任务直到线程池中的数量等于maximumPoolSize

关注点2 :适当的阻塞队列

  • java.lang.IllegalStateException: Queue full
  • 方法 抛出异常 返回特殊值 一直阻塞 超时退出
  • 插入方法 add(e) offer(e) put(e) offer(e,time,unit)
  • 移除方法 remove() poll() take() poll(time,unit)
  • 检查方法 element() peek() 不可用 不可用
  • ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
  • LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
  • PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
  • DelayQueue: 一个使用优先级队列实现的无界阻塞队列。
  • SynchronousQueue: 一个不存储元素的阻塞队列。
  • LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列。
  • LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。

关注点3 :明确拒绝策略

  • ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出RejectedExecutionException异常。 (默认)
  • ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,可是不抛出异常。
  • ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,而后从新尝试执行任务(重复此过程)
  • ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

说明:Executors 各个方法的弊端:

  • 1)newFixedThreadPool 和 newSingleThreadExecutor:
    • 主要问题是堆积的请求处理队列可能会耗费很是大的内存,甚至 OOM。
  • 2)newCachedThreadPool 和 newScheduledThreadPool:
    • 主要问题是线程数最大数是 Integer.MAX_VALUE,可能会建立数量很是多的线程,甚至 OOM。
相关文章
相关标签/搜索