【Android】线程池管理部分浅析

一、AsynTask

1、构造NuAsyncTask实例

在这里插入图片描述

该类是一个泛型类,取消了Process参数(因为更多情况下使用不到,保证接口的简洁性),只保留了Params,Result类型参数;

另外,构造函数必须要求传入一个workName,以便来跟踪任务的执行时间。因为AsyncTask任务可以调用取消接口,所以该类为了

保证功能的一致性,定义了一个NuFutureRunnable类,以来可以取消提交的任务。

2、抽象接口定义

在这里插入图片描述

抽象接口的定义,同AsyncTask的 doInBackground,onPostExecute;因为不需要关注Process,所以取消了onProgressUpdate接口的定义;用户在使用的时候,只要按照

创建一个NuAsyncTask对象,实现抽象函数接口,doInBackground保证在子线程执行任务,onPostExecute保证在UI线程回调结果。

3、任务的提交与执行

在这里插入图片描述

提交任务,可以调用execute接口或executeOnExecute接口,如果是execute接口,框架层有个默认的线程池执行器;如果是executeOnExecute,外部可以根据自身需求来指定执行器,最终会调用到

NuExecutor的submit接口,提交一个“未来任务”,并且执行接口回调到UI线程,由上面代码可以看到,在线程池整理框架的基础上,重新包装调用了抽象接口doInBackground与onPostExecute,通过这样的包装,

可以满足不同用户的偏好需求,但是线程任务的执行,都是统一通过线程池整理框架进行分配管理。

4、任务的取消

在这里插入图片描述

取消可以调用cancel接口,该接口会原子操作保存当前取消的值,用户可以根据isCancelled来判断当前的任务取消状态;然后就会调用mFutureRunnable的cancel接口,

尝试的取消任务,否则直接返回false,无需要做任何取消动作;监听是否取消,用户可以通过复写接口onCancelled接口来处理取消后的任务。

5、总结

由此可见,NuAsyncTask的用法跟AsyncTask的用户完全类似,并且简化的使用方式,使得使用起来更简洁易用,通过最后巧妙的包装,内部的实现转接到了NuExecutor类,跟之前的线程池管理巧妙

的关联起来,从而实现的统一管理的目的。

二、HandlerThread

1、构造NuThreadHandler实例

在这里插入图片描述

如上图所示:传入一个ThreadInfo对象,该对象描述了一个线程的名字,优先级等信息;然后调用构造的核心方法createHandler,在该方法里面,内部根据threadinfo信息创建了一个HandlerThread对象,

接着实例化Hanlder来处理异步消息。

由此可见,NuThreadHandler内部实现的ThreadHandler,这样就避免了外部随意创建HandlerThread对象,导致线程不可控的现象。

2、对外暴露接口 send与post方式

在这里插入图片描述

可以通过send的方式发送一个Message对象,也可以通过post的方式发送一个Runnable对象,可以根据不同的需求来调用响应的接口方法,核心的实现代码都是在sendMessageInner,代码如下:

在这里插入图片描述

step1:Message.what采用的是一个全局唯一值WHAT_GLOBAL_TOKEN,目的是为了统一标识所有的send或post方式发送的消息,便于取消所有的任务

step2:区分srcObj是Message对象还是Runnable对象,如果是Message对象,m.obj来记录srcMsg的what值,其他信息保存到m.data(Bundle)对象中去,

      如果未Runnable对象,直接保存到m.obj中去

step3:最后,调用内部异步Handler对象,发送当前的消息,该消息在doMessage中处理。

3、消息处理doMessage

在这里插入图片描述

首先,根据发送过来的Message对象中obj进行区分,根据上面步骤的分析,如果obj为Runnable对象,说明采用的post方式;如果对象时Message对象,说明采用的是send方式。

其次,如果是Runnable对象,直接执行NuRunnable.run方法,因为NuRunnable对于任务的执行时间有统计,所以,改出不在进行统计。

最后,如果是Message对象,需要通过MSG_OBJ获取到原始的srcMessage对象,然后交由 handleMessage(需要子类实现)接口进行处理,并统计了该Message处理的时长

4、任务取消cancel

在这里插入图片描述

取消任务,可以根据 what方式取消,也可以根据Runnable方式取消,也可以取消所有的消息,调用的接口是Handler.removeMessages接口,第一个参数都表示what,第二参数表示obj

5、删除消息removeMessages原理解读

在这里插入图片描述

三、ThreadPoolExecutor

1、再包装该类

如下图所示,通过继承的方式包装该类,以后项目中有使用ThreadPoolExecutor类的地方,都统一使用NuExecutor类

该类只暴露的2个构造函数,简化用户的使用,同时,外部实例化的时候,必须制定一个该线程池的名称,便于追本溯源。

在这里插入图片描述

2、execute接口包装

如下图所示,对于之前的接口标识了@Deprecated,原则:Deprecated的接口禁止调用

新增了 NuRunnable参数接口,外部应当调用该接口(NuRunnable是单个任务执行器,包含了任务时长统计等行为,本文不细阐述)

在这里插入图片描述

3、submit接口包装

如下图所示,同execute原则,原始的接口进行弃用

新增参数为NuRunnable,返回值为NuFutureRunnable的接口(NuFutureRunnable是对FutureTask的包装)

在这里插入图片描述

4、线程池线程创建

如下图所示,线程池中线程的命名规则:nuBrowser-thread-executorName-number

这样便于区分线程池(线程池线程只是执行Runnable,所以每个任务的执行时长在Runnable中进行统计,本文不再赘述NuRunnable类,知晓该类职责即可)

另外,每个线程统计了该线程的存活时长(如果需要,甚至可以统计该线程执行了的任务个数等信息,根据项目需要进行扩展)

在这里插入图片描述

5、线程中断监控

如下图所示,在NuExecutor中有两个方法,每当线程池开始执行任务时候,会回调beforeExecute和afterExecute方法,可以在此方法记录当前线程将要执行的任务

在线程被中断,即被调用到interrupt接口的时候,统计当前的任务信息,并进行输出,便于跟踪问题。

在这里插入图片描述

总结:在今后项目中,凡是用到线程池概念或者ThreadPoolExecutor类的地方,都必须统一使用NuExecutor类,这样便于项目中进行必要信息的统计采集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值