包括UI人机交互操作,所有的代码都运行在线程环境内,系统启动的代码运行在主线程中。
撇开主线程,某种意义上来说,可以让所有的代码进行业务封装,让它们作为独立的任务或者函数,让线程去完成。
线程可以理解为工作的人,而任务或函数就是待完成的工作。线程池则是整装待发的工作人员集合。
当一个任务产生时,将会添加到线程池中,由线程池分派线程进行任务的执行,如果整个应用都按照这个设计框架去完成,那么在线程池中同步可添加同类任务的执行时长(最长、最短、平均,次数),可以打印出当前所有正在执行的任务,这样对于整个系统的运行状态可以有比较好的把控。
单队列线程池的实现思路:
单队列线程池的属性信息:
1. 一个任务队列
任务队列具有长度上限,当调用添加任务的接口时,任务会被按先进先出原则添加到该队列中,同时触发空闲的线程获取任务进行执行。
2. 最小工作线程数和最大工作线程数
当有线程空闲并达到一定的时长后,应当释放一些线程,最小线程数可到达最小工作线程数,反之,当任务队列中任务堆积时,可扩大线程数,最大可到最大工作线程数。
如果不希望进行线程数的动态调整,那么可让最小和最大工作线程数相等即可。
3. 任务执行统计信息
相同任务或函数的,标识为同类任务的统计,能得到同类任务的最大执行时长、最小执行时长、执行次数、平均耗费时长。
正在执行的任务信息,开始执行时间、任务标识、执行时长等。
4. 线程池状态回调接口
当线程池出现异常状态时进行的回调,如任务队列达长度达到预警和溢出的状态,有任务执行发生异常崩溃的情况等等。
单队列线程池的接口信息:
1. 启动接口
当调用本接口时,启动最小工作线程数,线程开始待工,并标识线程池进行工作状态。
2. 停止接口
当调用本接口时,先标识线程池退出工作状态,并关闭所有的工作线程,同时清空任务队列。
3. 添加任务
当调用本接口时,一个任务被添加到任务队列,任务应继承必要的规则,以便执行时能够进行任务代码的触发。任务添加时,能够添加一个监听回调,从而在任务开始执行,执行完成时能获得对应的回调。
4. 得到线程池状态
当调用本接口时,能够获得当前的线程数信息(总线程数、空闲线程数,各线程执行的累计任务数),获得任务执行统计信息,获得当前正在执行的任务信息。
单队列线程池的内部流程:
1. 具有一个定时器,能够周期性打印每个周期的任务执行统计信息
2.能够检测线程数量的情况,抉择增加或消减线程,达到动态调整线程数的目的。
多队列线程池的实现思路
软件运行时,有些任务是需要有序执行的,也就是说B任务需要等到A任务完成后再执行,C任务需要等B任务的完成。
一种方式是外部控制,等到A任务完成后,再把B任务添加到线程池。这里提供的思路是由线程池内部实现该逻辑,对需要排队执行的任务,创建统一的串行号,对于线程池而言,相同串行号的任务按照先进先执行,并且不能并发执行的逻辑进行调度。
上述逻辑下,会为线程池中的每个线程创建一个队列,对应线程从对应队列上获取任务进行执行。当添加任务时,所有注册对应的串行号到对应的线程队列,而后相同的串行号的任务都将添加到对应的线程队列,从而保障串行号相同的任务得到串行化的执行。
备注:当新的串行号到达时,将分配当前注册最少的线程队列进行优先注册,以保障任务分配的相对均衡。
把这种线程池称之为多队列线程池的实现。
真实实现业务中,可以根据实际情况创建多个不同的线程池,不同的业务种类结合实际执行开销,放入到不同的线程池中,最终实现整个软件框架的代码都通过线程池执行的流程,进而提提高对软件执行状态的把控。
进而对于定时器的把控调整,定时器实际就只是负责产生任务,不在负责任务的执行,而任务的真实执行还是放置到线程池中,进而达到统一化的效果。