线程池ThreadPoolExecutor
状态:
Runing:允许提交并且处理任务
shutdown:不允许提交新的任务,但是会处理完已经提交的任务
stop 不允许提交新的任务,也不会处理阻塞队列中的未执行任务,并且设置正在执行线程的中断标志位
tidying所有任务执行完毕,池中工作的线程数为0
terminated terminated钩子方法执行完毕
线程池的shutdown方法,将线程池由Running转化为shutdown
线程池的shutdownNow方法,将线程池由RUNning或者shutdown状态转化为stop
shutdown何STOP状态先会转变成TIDYING再转变为terminated、
线程池工作原理
当调用线程池execute方法添加一个任务时,线程池会做如下判断:
1、如果有空闲线程,直接执行
2、如果无空闲线程,且当前线程数小于corePoolsize,创建新线程执行任务
3、如果无空闲线程,且当前线程数等于corePoolsize,同时阻塞队列未满,加入阻塞队列
4、如果无空闲线程,同时阻塞队列已满,同时当前线程数小于maximumPoolsize线程数,创建新线程
5、如果无空闲线程,当前线程数等于maximumPoolSize,执行阻塞策略
ThreadPoolExecutor参数说明
corePoolSize 线程池中核心线程数的最大值
maximumPoolSize:线程池中能拥有最多线程数
keepAliveTime:表示空闲线程的存活时间
TimeUnit unit:表示keepAliveTime的单位
workQueue:用于缓存任务的阻塞队列
threadFactory:指定创建线程的工厂
ThreadPoolExecutor线程池推荐了三种阻塞队列
synchronousQueue:有界队列,一个不存储元素的阻塞队列,每一个插入操作,必须等待另外线程的调用,否则插入一直阻塞
linkedBlockingQueue:基于链表结构的无界阻塞队列,默认容量Integer.MAX_VALUE
arrayBlockingQueue :有界队列,一个基于数组的有界队列,一旦创建就不能扩容
handler拒绝策略
触发条件:当队列已满,并且当前线程数等于maximumPoolSize,线程池拒绝添加新任务时采取的策略。
ThreadPoolExecutor.AbortPolicy:抛出异常,默认策略
ThreadPoolExecutor.DiscardPolicy抛弃当前的任务
ThreadPoolExecutor.CallerRunsPolicy:由线程池提交任务的线程来执行
ThreadPoolExecutor.DiscardOldestPolicy:抛弃最旧的任务
Executors类
底层实现的便是ThreadPoolExecutor
Executors.newCachedThreadPool(),
Executors.newFixedThreadPool(int)固定大小的线程池
Executors.newSingleThreadExecutor()单个后台线程
1.2)线程池执行时,Callable的call方法(Runnable的run方法)抛出异常后,会出现什么?
在上面的例子中我们可以看到,线程池无论是执行Callable还是Runnable,调用返回的Future对象get()方法时需要处理两种异常(如果是调用get(timeout)方法,需要处理三种异常),如下:
//在线程池上运行
Future<Object> future = threadPool.submit(callable);
try {
System.out.println("feature.get");
Object x = future.get(900,TimeUnit.MILLISECONDS);
System.out.println(x);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
System.out.println("execute exception...");
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
如果get方法被打断,进入InterruptedException异常;
如果线程执行过程(call、run方法)中抛出异常,进入ExecutionException异常;
如果get方法超时,进入TimeoutException异常;
1.3)submit()和execute()方法区别:
ExecutorService、ScheduledExecutorService接口的submit()和execute()方法都是把任务提交到线程池中,但二者的区别是
接收的参数不一样,execute只能接收Runnable类型、submit可以接收Runnable和Callable两种类型;
submit有返回值,而execute没有返回值;submit方便Exception处理;
————————————————
版权声明:本文为CSDN博主「赶路人儿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liuxiao723846/article/details/108026782