作为一个程序员,平时关于线程也是使用的肯定很频繁,举个例子开启无数线程跑的同时就好像一个没有红绿灯的十字路口无数的汽车在通行,结局可想而知,而本文就是介绍多线程的管理者ThreadPoolExecutor线程池。
java多线程池的支持——ThreadPoolExecutor
ThreadPoolExecture实现原理
Step1:调用execute方法创建新线程,首先检查CorePool 核心线程数量,如果少于CorePoolSize则去创建新的线程,反之则进入Step2
Step2:CoolPool内线程数量已满,则将线程加入BlockingQueue(等待队列)如果BlockingQueue已满则进入Step3
Step3:如果池中的线程数量大于CorePoolSize,BlockingQueue已满,并且
1.线程池中数量小于corepoolsize,则创建新线程去执行任务
2.线程池中数量等于corepoolsize,通过handler指定的策略来处理此任务,优先级:核心线程coopoolsize,任务队列workqueue,最大线程maximumPoolSize,三者都满了之后,使用handler处理被拒绝的任务
3.线程池中数量大于corepoolsize,如果某个线程执行完空闲时间超过keepAliveTime的时间该线程将被终止,线程池调整池中线程数
关于线程池的构造方法:
publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,
TimeUnit unit,BlockingQueue workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {
if(corePoolSize <0|| maximumPoolSize<=0||maximumPoolSize< corePoolSize || keepAliveTime <0)throw newIllegalArgumentException();
if(workQueue ==null|| threadFactory ==null|| handler ==null)throw newNullPointerException();
this.corePoolSize= corePoolSize;
this.maximumPoolSize=maximumPoolSize;
this.workQueue= workQueue;
this.keepAliveTime= unit.toNanos(keepAliveTime);
this.threadFactory= threadFactory;
this.handler= handler;
}
构造方法参数解释
corePoolSize 线程池核心线程数量
maximumPoolSize 线程池最大容量大小
keepAliveTime 线程池维护线程的空闲时间
TimeUnit unit时间单位
BlockingQueue workQueue 等待队列
ThreadFactory 线程工厂
RejectedExecutionHandler 拒绝策略
对于一些参数的理解:
关于blockQueue:
1.ArrayBlockingQueue 有界队列,基于数据结构的数组类型等待队列,先进先出,newArrayBlockingQueue(?) ?定义队列长度。
2.LinkedBlockingQueue 无界队列,基于链表结构的等待队列,先进先出,吞吐量大于ArrayBlockingQueue。
3.syncchronousQueue 直接提交,一个不存储元素的工作阻塞队列,前一个线程对象不调用移除操作完全移除之后,后一个线程将一直处于阻塞状态即前一个任务完成之后才会执行下一个任务,吞吐量大于LinkedBlockingQueue,Executors.newCachedThreadPool使用了此阻塞队列
4.priorityQueue 一个具有无限优先级的阻塞队列
关于threadfactory
创建线程的工厂
关于拒绝策略rejectedExecutionHandler
当队列和线程池都满了,说明线程池处于饱和状态,这时候我们需要通过handler执行拒绝策略,无法处理新建线程时向执行。四种策略:
1.ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
2.ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
4.ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
启动线程池
一个线程任务通过ThreadPool.excute(new Runnable)添加执行。任务执行的方法就是Runnable对象的run方法,使用excute适用于提交不需要返回值的任务,当需要提交返回值的任务时需要使用submit()方法。
关闭线程池
原理:遍历线程池中的所有工作线程,然后调用线程的interrupt方法终止线程,所以无法响应中断的线程将永远无法停止。
1.shutdownnow
将线程职为STOP状态,然后尝试停止所有正在执行或者短暂暂停的线程,并返回正在等待的任务队列。
2.shutdown
将线程置为SHUTDOWN状态,然后中断所有没有正在执行的工作线程。
关于介绍暂时到这边,后续继续努力!