概述: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。