线程池参数解析以及提交任务的流程
线程池的6个参数
ThreadPoolExecutor(Executor接口的实现类)提供的构造方法:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- corePoolSize:核心线程数目。当提交一个新任务到线程池时,线程池会创建一个线程来执行任务,等到需要执行的任务数大于核心线程池的大小,就不再创建了
- BlockingQueue workQueue:保存等待执行的任务的阻塞队列。
有4种阻塞队列:
ArrayBlockingQueue【基于数组结构的有界阻塞队列,先进先出排序】
LinkedBlockingQueue【基于链表结构,先进先出,吞吐量高于前者。静态工厂方法Executors.newFixedThreadPool()】
SynchronousQueue【不存储元素,插入操作必须等到另一个移除,吞吐量高于前者。静态工厂方法Executors.newCacheedThreadPool()】
PriorityBlockingQueue【具有优先级】 - maximumPoolSize:线程池最大数。当队列满了之后,并且线程数未超过最大线程数,就会再创建新线程执行任务。
- ThreadFactory():线程工厂,给线程取名字
new ThreadFactoryBuilder().setNameFormat(“xx-task-%d”).build(); - RejectedExecutionHandler:饱和策略,当队列和线程池都满了,拒绝任务。有4种,通常是AbortPolicy直接抛出异常;
- keepAliveTime:闲置线程存活时间,时间越大,存活时间越多,利用率更高
TimeUnit.MILLISECONDS:时间单位毫秒
线程池处理新提交的任务
当一个任务提交到线程池,线程池的处理流程:
总结:任务进来之后,线程池会逐一判断 corePoolSize 、workQueue 、maxPoolSize ,如果依然不能满足需求,则会拒绝任务。
有两种方法向线程池提交任务:
- execute():提交后不需要返回值,对应的是Runnable类的实例任务
threadsPool.execute(new Runnable() {
@Override
public void run() {
//TO DO
}
});
- submit():移交后需要返回值,返回future类型的对象,通过future的get方法获取。
Future<Object> future = executor.submit(task);
try{
Object s = future.get();
} catch (InterruptedException e) {
//
} catch (ExecutionException e) {
//
} finally {
executor.shutdown();
}
关闭线程池的方法:
1.shutdown():一般都用这个
2.shutdownNow():任务不一定要执行完