前言
本插件内容是结合多家博客的精华改造而成的
该插件主要是基于github.com/Knight-ZXW/… 的基础上细化改造的
目标
线程优化便是将自己代码中的线程以及各种sdk 中创建的线程都收敛到一致的线程池中,便利线程的管理。
咱们知道创建线程的办法有多种:
new Threadnew ScheduledThreadPoolExecutornew ThreadPoolExecutornew FixedThreadPoolnew CachedThreadPoolExecutors.newSingleThreadExecutor()new HandlerThread
跟着业务的胀大以及接入各种三方sdk越来越多,那么在咱们的apk中将存在很多无法管控的Thread实例以及 ThreadPoolExecutor 实例。
所以要到达线程收敛的意图便是要将 各种 new Thread 以及new ThreadPoolExecutor 等等实例都变成 一个 ,比方 new ProxyThread 、new PThreadPoolExecutor
以某一个sdk为例,线程收敛前某sdk的现状如下:
优化后:

new Thread 以及new ThreadPoolExecutor 相关代码都改了
问题来了,即便都改成了new ProxyThread 、new PThreadPoolExecutor,这不是仍然有很多线程和线程池的实例吗,仍然没有到达收敛的意图?
的确,要想到达收敛的意图,还需求做一些工作,拿PThreadPoolExecutor 为例
咱们在PThreadPoolExecutor 重写了ThreadPoolExecutor中的 execute 办法和 submit办法,当有人向线程池中提交使命时,咱们这儿并没有开启线程,而是通过 DefaultThreadPoolExecutor.getHCoreThreadPool().execute(command) 将使命丢到了新的线程池中。 所以可以看出PThreadPoolExecutor 并不是真实的线程池,真实的线程池是 getHCoreThreadPool(),它是一个单例。
public class PThreadPoolExecutor extends ThreadPoolExecutor {
//..........
//.........
@Override
public void execute(Runnable command) {
if (!SuperThreadPoolManager.isProxyThreadEnable()) {
super.execute(command);
return;
}
try {
DefaultThreadPoolExecutor.getHCoreThreadPool().execute(command);
} catch (OutOfMemoryError error) {
DefaultThreadPoolExecutor.getExtraThreadPool().execute(command);
}
}
@Override
public Future<?> submit(Runnable task) {
if (!SuperThreadPoolManager.isProxyThreadEnable()) {
return super.submit(task);
}
try {
return DefaultThreadPoolExecutor.getHCoreThreadPool().submit(task);
} catch (OutOfMemoryError error) {
return DefaultThreadPoolExecutor.getExtraThreadPool().submit(task);
}
}
@Override
public <T> Future<T> submit(Callable<T> task) {
if (!SuperThreadPoolManager.isProxyThreadEnable()) {
return super.submit(task);
}
try {
return DefaultThreadPoolExecutor.getHCoreThreadPool().submit(task);
} catch (OutOfMemoryError error) {
return DefaultThreadPoolExecutor.getExtraThreadPool().submit(task);
}
}
}
运用
- 项意图根目录下的
build.gradle中增加
classpath 'io.github.heyan224:lancet-plugin:0.0.6'
- app目录下的
build.gradle中增加
implementation 'io.github.heyan224:lancet-runtime:0.0.2'
- 仍是在 app目录下的
build.gradle中增加如下的配置
apply plugin: 'LancetX'
LancetX{
enable true
enableInDebug true
weaveGroup {
threadOptimize {
enable false
whiteNames = [
"com/bb",
"com/aa",
"com/xx"
]
blackNames = [
]
}
}
}
这儿解释几个关键的字段:
threadOptimize { // 线程优化配置项
enable true // 开关
whiteNames = [ // 白名单,咱们可以增加白名单,来指定特定的几个sdk来进行线程优化
"com/bb",
"com/aa",
"com/xx"
]
blackNames = [ // 黑名单
]
}
- 最后一步便是来完成 咱们自己的
ProxyThreadPThreadPoolExecutor代码了,以及Thread和ProxyThread的映射,ThreadPoolExecutor和PThreadPoolExecutor的映射
也便是咱们要告知字节码修正插件,咱们想要修正哪些类,比方咱们即将修正 Thread 类,修正为 ProxyThread,代码如下图。
另外 ProxyThread 、PThreadPoolExecutor、getHCoreThreadPool()的完成都已在库房中了
注意点
线程收敛到这儿其实还没开始,由于真实重要的是咱们的代理线程池的参数应该怎么配置。
咱们都知道线程池有几个重要的参数需求深思熟虑
- 线程池核心线程数
- 线程池最大线程数
- 使命等待行列
- 线程空闲多久要收回,也便是keepAliveTime
- 线程使命拒绝战略的拟定 RejectedExecutionHandler
这几个参数的拟定对于线程收敛很重要。

