大家好,这里是淇妙小屋,一个分享技术,分享生活的博主,后续会发布更多MySQL,Redis,并发,JVM,分布式等面试热点知识,以及Java学习路线,面试重点,职业规划,面经等相关博客 转载请标明出处!
应用程序通过Executor框架控制上层的调度
下层的调度有OS内核控制,不受应用程序控制
Executor架构分为三个部分
用于控制任务的执行,获得异步任务的执行状态,执行结果
向线程池提交Callable任务,线程池会返回一个Future对象供我们查看异步任务的执行状态,执行结果
Future<String>future=executor.submit(new Callable<String>(){});
//上下等价
RunnableFuture<String>future=new FutureTask<String>(异步任务);
executor.execute(future);
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
//略
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
参数介绍
过程](../p/execute()过程.png)
尝试将线程池的状态更改为 TERMINATED,只有以下2种情况才能成功
第4步大部分情况都不会成功
线程池状态变为SHUTDOWN后,线程池不会再接受新的任务,但已经接受的任务仍会继续执行,当所有任务执行完后,线程检测到线程池状态为SHUTDOWN并且任务队列空了,那么线程会执行退出操作——在退出操作中,每个线程都会执行一次 tryTerminal(),最后一个退出的线程可以成功销毁线程池
shutdownNow()移除任务队列中所有未执行的任务,从而实现快速关闭线程池
在线程池中预先创建一个线程
在线程池中创建所有的核心线程
如果线程池中的线程数目>corePoolSize,那么多余的线程一旦空闲超过keepAliveTime,就会销毁线程,直到线程数目==corePoolSize
我的个人理解
我认为线程池的本意是让核心数量的线程工作着,任务队列起到一个缓冲的作用,最大线程数目这个参数更像是无奈之举,在任务非常多的情况下做最后的努力,去新建线程来帮助处理任务
原生的线程池偏向于 CPU密集型,任务过多时不是创建更多的线程,而是先缓存任务,让核心线程去处理
而像Tomcat这种业务场景,是 IO密集型,原生的线程池并不合适,需要定制(Tomcat的线程池就是定制的)
ScheduledThreadPoolExecutor中
schedule(),scheduleAtFixedRate(),scheduleWithFixedDelay(),submit(),execute()的逻辑基本相同
接下来以schedule()为例进行讲解
ScheduledThreadPool中,任务封装为ScheduledFutureTask后,直接进入任务队列,然后由线程从任务队列中获取ScheduledFutureTask执行
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。