随着cpu核数越来越多,不可避免的利用多线程技术以充分利用其计算能力,所以多线程技术是服务端开发人员必须掌握的技术。
随着线程的创建和销毁,都涉及到系统的调用,比较消耗系统资源,所以就引入了线程池技术,避免频繁的创建和销毁线程。
在java中有一个工具类,可以为我们创建一个线程池,其本质就是new一个对象。线程池几乎也是面试题必考的问题。本文结合源码,说说的工作原理。
线程池创建
先看一下参数最全的构造方法:
public class ThreadPoolExecutor {
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime, TimeUnit unit, BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExceptionHandler handler){
}
}
: 线程池中的核心线程数,说白了就是,即便是线程池里没有任何任务,也会有个线程在候着等任务。: 最大线程数,不管你提交多少任务,线程池里最多工作线程就是。: 线程的存活时间。当线程池里的线程数大于时,如果登陆时长还没有任务执行,则线程退出。unit: 这个是用来指定的单位,比如秒:.。: 一个阻塞队列,提交的任务将会被放入到这个队列里。:线程工厂,用来创建线程,主要是为了给线程命名,默认工厂的线程名:pool-1–3。:拒绝策略,当线程池里线程被耗尽了,且队列也满了的时候会调用。
上面就是创建线程池用到的参数的详细解释。
线程池执行流程
这里用一个图来说明线程池的执行过程。
任务被提交到线程池,会先判断当前线程数量是否小于,如果小于则创建线程来执行提交的任务,否则将任务放入队列中,如果满了,则判断当前线程数量是否小于,如果小于则创建线程执行任务,否则就会调用,以表示线程池拒绝接受任务。
这里以”1.8.0_171″的源代码为例,看一下具体实现。
先看一下线程池的方法
①. 判断当前活跃线程数是否小于,如果小于,则调用创建线程执行任务 ②. 如果不小于,则将任务添加到队列中。 ③. 如果放入失败,则创建线程执行任务,如果创建线程失败(当前线程数不小于时),就会调用(内部调用)拒绝接受任务。
再看下的方法实现
这块代码是在创建非核心线程时,即core为false。判断当前线程数是否大于等于,如果大于等于则返回false,即上边说到③中的创建线程失败的情况。
方法的下半部分:
①. 创建对象,用时也会实例化一个对象。
②. 启动这个线程
再到Woker里面看看其实现
可以看到在创建时会调用来创建一个线程,上面②中启动一个线程就会触发的run方法被线程调用。实现了接口。
接下来看看方法的逻辑
线程调用,会while循环调用方法从队列里读取任务,然后执行任务。只要方法不返回null,此线程就不会退出。
最后在看看方法实现
①. 先不管ut,这个变量的默认值是false,wc > 则是判断当前线程数是否大于。
②. 如果当前线程数大于,这回调用的poll方法获取任务,超时时间就是。如果超过时长,poll返回了null,上边提到的while循环就会退出,线程也就执行完了,如果当前线程数小于,则会调用的take方法阻塞在当前。
———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666