前言
本插件内容是结合多家博客的精华改造而成的
该插件主要是基于github.com/Knight-ZXW/… 的基础上细化改造的
目标
线程优化便是将自己代码中的线程以及各种sdk 中创建的线程都收敛到一致的线程池中,便利线程的管理。
咱们知道创建线程的办法有多种:
new Thread
new ScheduledThreadPoolExecutor
new ThreadPoolExecutor
new FixedThreadPool
new CachedThreadPool
Executors.newSingleThreadExecutor()
new HandlerThread
跟着业务的胀大以及接入各种三方sdk越来越多,那么在咱们的apk中将存在很多无法管控的Thread
实例以及 ThreadPoolExecutor
实例。
所以要到达线程收敛的意图便是要将 各种 new Thread
以及new ThreadPoolExecutor
等等实例都变成 一个 ,比方 new ProxyThread
、new PThreadPoolExecutor
以某一个sdk为例,线程收敛前某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 = [ // 黑名单
]
}
- 最后一步便是来完成 咱们自己的
ProxyThread
PThreadPoolExecutor
代码了,以及Thread
和ProxyThread
的映射,ThreadPoolExecutor
和PThreadPoolExecutor
的映射
也便是咱们要告知字节码修正插件,咱们想要修正哪些类,比方咱们即将修正 Thread
类,修正为 ProxyThread
,代码如下图。
另外 ProxyThread
、PThreadPoolExecutor
、getHCoreThreadPool()
的完成都已在库房中了
注意点
线程收敛到这儿其实还没开始,由于真实重要的是咱们的代理线程池的参数应该怎么配置。
咱们都知道线程池有几个重要的参数需求深思熟虑
- 线程池核心线程数
- 线程池最大线程数
- 使命等待行列
- 线程空闲多久要收回,也便是keepAliveTime
- 线程使命拒绝战略的拟定 RejectedExecutionHandler
这几个参数的拟定对于线程收敛很重要。