在 Executoors 中的 newChachedThreadPool, newFixedThreadPool, newScheduledThreadExecutor 的工厂方法返回的都是 ThreadPoolExecutor 对象。若是默认的执行策略不能知足需求,能够经过 ThreadPoolExecutor 的构造函数进行实例化,根据本身的需求定制。 html
ThreadPoolExecutor(int corePoolSize,//线程池基本大小
int maximumPoolSize, //线程池最大尺寸
long keepAliveTime, //线程空闲后的存活时间
TimeUnit unit,
BlockingQueue<Runnable> workQueue, //任务队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler) //饱和策略
复制代码
newFixedThreadPool 工厂方法将线程池的基本大小和最大大小都设置为参数中指定的值,并且建立的线程池不会超时。java
newCachedThreadPool工厂方法将线程池的最大大小设置为Integer.MAX_VALUE,将基本大小设置为0,并将超时设置为1分钟,这种方法建立出来的线程池能够被无限扩展,而且当需求下降时会自动收缩。git
使用BlokcingQueue来保存等待执行的任务。基本的队列有无界队列,有界队列和同步移交。队列的选择和线程池的其余配置参数有关。编程
newFixedThreadPool 和 newSingleThreadExecutor 在默认状况下使用一个无界的LinkedBlockingQueue。若是全部工做者线程都处于忙碌状态, 那么任务将在队列中等待。缓存
有界队列包括ArrayBlockingQueue以及有界的LinkedBlockingQueue和PriorityBlockingQueue。在使用有界队列时,队列的大小须要和线程池的大小一块儿调节。线程池小而队列较大,有助于减小内存使用量,下降CPU的使用率,同时还能够减小上下文切换,可是可能会限制吞吐量。并发
对于很是大或无界的线程池,能够经过SynchronousQueue来避免任务排队,以及直接将任务从生产者移交给工做者线程。这个队列的put方法会阻塞,直到有线程准备从队列里面take,因此本质上SynchronousQueue并非Queue,它不存储任何东西,它只是在移交东西,是一种在线程之间进行移交的机制。要将一个任务放到其中,必须有另外一个线程正在等待接受这个元素。若是没有线程正在等待,而且线程池的当前大小小于最大值,那么ThreadPoolExecutor将建立一个新的线程,不然这个任务奖杯拒绝。在 newCachedThreadPool中采用了SynchronousQueue。函数
当有界对垒被填满后,饱和策略开始发挥做用。经过setRejectedExecutionHandler来修改。有如下四种饱和策略。spa
线程池在建立线程时,经过线程工厂方法来完成。在默认的ThreadFactory接口中只定义了一个方法newThread,每当建立新线程时都会调用这个方法。能够本身建立一个类实现默认的ThreadFactory接口来定制本身的线程工厂。线程
ThreadPoolExecutor是能够扩展的,它提供了几个能够在子类中改写的方法:beforeExecute, afterExecute, terminated。在执行任务的线程中将调用beforeExecute和afterExecute方法。不管是正常返回仍是抛出异常,afterExecute都被调用。若是beforeExecute抛出一个RuntimeException,任务将不被执行,afterExecute也不会调用。rest