一、核心概念区分
1.1 Executor(接口)
Executor
是 Java 并发包中的基础接口,代表一个执行任务的抽象,只有一个方法:
java
public interface Executor {
void execute(Runnable command);
}
1.2 Executors(工具类)
Executors
是一个工厂工具类,提供创建各种预配置 ExecutorService
实例的静态方法:
java
public class Executors {
public static ExecutorService newFixedThreadPool(int nThreads) {...}
public static ExecutorService newCachedThreadPool() {...}
// 其他工厂方法...
}
二、使用场景对比
2.1 Executor 使用场景
适用情况:
- 需要自定义任务执行策略
- 与现有框架集成(如Guava的MoreExecutors)
- 实现特定线程管理逻辑
代码示例:
kotlin
// 自定义直接执行器(同步执行)
val directExecutor = Executor { command -> command.run() }
// 自定义后台执行器
val backgroundExecutor = Executor { command ->
Thread(command).start()
}
2.2 Executors 使用场景
适用情况:
- 快速创建标准线程池
- 需要预定义线程池配置
- 常规异步任务处理
代码示例:
kotlin
// 固定大小线程池
val fixedPool = Executors.newFixedThreadPool(4)
// 缓存线程池(自动扩容)
val cachedPool = Executors.newCachedThreadPool()
// 单线程顺序执行
val singleThread = Executors.newSingleThreadExecutor()
三、核心区别详解
维度 | Executor | Executors |
---|---|---|
类型 | 接口 | 工具类 |
主要作用 | 定义执行契约 | 创建线程池实例 |
方法数量 | 1个(execute) | 多个工厂方法 |
扩展性 | 高(可自定义实现) | 低(使用预置配置) |
使用复杂度 | 高(需自行实现) | 低(开箱即用) |
生命周期管理 | 需手动实现 | 内置shutdown等管理 |
四、Android 中的特殊注意事项
4.1 主线程执行器
Android 特有实现(非Executors提供):
kotlin
val mainThreadExecutor = ContextCompat.getMainExecutor(context)
// 等同于Handler(Looper.getMainLooper())
4.2 配置建议
避免使用的线程池:
kotlin
// 不推荐 - 可能创建过多线程
Executors.newCachedThreadPool()
// 替代方案 - 限制最大线程数
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2)
推荐配置:
kotlin
// 最佳实践:自定义线程工厂
val threadFactory = ThreadFactory { r ->
Thread(r, "AppThread-${atomicInt.incrementAndGet()}").apply {
priority = Process.THREAD_PRIORITY_BACKGROUND
}
}
val optimalPool = ThreadPoolExecutor(
4, // 核心线程
16, // 最大线程
60L, TimeUnit.SECONDS, // 空闲超时
LinkedBlockingQueue(64), // 任务队列
threadFactory
)
五、完整代码示例
5.1 自定义Executor实现
kotlin
class PriorityExecutor : Executor {
private val workerQueue = PriorityBlockingQueue<Runnable>(11) { a, b ->
(a as PriorityTask).compareTo(b as PriorityTask)
}
override fun execute(command: Runnable) {
workerQueue.put(command)
if (activeCount < MAX_WORKERS) {
startNewWorker()
}
}
private fun startNewWorker() {
// ...启动处理线程...
}
}
// 使用
val priorityExecutor = PriorityExecutor()
priorityExecutor.execute(HighPriorityTask())
5.2 Executors典型用法
kotlin
// 1. IO密集型任务池
val ioPool = Executors.newFixedThreadPool(8)
// 2. 定时任务调度
val scheduler = Executors.newScheduledThreadPool(4)
scheduler.scheduleAtFixedRate({
// 定期执行
}, 1, 1, TimeUnit.SECONDS)
// 3. 单线程顺序处理
val serialExecutor = Executors.newSingleThreadExecutor()
serialExecutor.execute { /* 任务1 */ }
serialExecutor.execute { /* 任务2 */ } // 保证顺序执行
六、内存与性能优化
6.1 线程池泄漏检测
kotlin
class LeakDetectorExecutor(
private val delegate: Executor,
private val tag: String
) : Executor {
private val trackedTasks = Collections.synchronizedSet(mutableSetOf<Runnable>())
override fun execute(command: Runnable) {
val wrapped = Runnable {
trackedTasks.remove(command)
command.run()
}
trackedTasks.add(wrapped)
delegate.execute(wrapped)
}
fun checkLeaks() {
if (trackedTasks.isNotEmpty()) {
Log.w("LeakDetector", "Potential leaks in $tag: ${trackedTasks.size}")
}
}
}
6.2 生命周期感知执行器
kotlin
class LifecycleAwareExecutor(
private val lifecycle: Lifecycle,
private val delegate: Executor
) : Executor, LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun cleanup() {
// 释放资源
}
override fun execute(command: Runnable) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
delegate.execute(command)
}
}
}
七、与Kotlin协程的交互
7.1 作为协程调度器
kotlin
val customDispatcher = Executors.newFixedThreadPool(4)
.asCoroutineDispatcher()
// 使用
CoroutineScope(customDispatcher).launch {
// 在Executor线程池中执行
}
7.2 替代方案比较
方式 | 优点 | 缺点 |
---|---|---|
传统Executor | 精细控制线程行为 | 手动管理复杂 |
协程Dispatchers | 结构化并发,轻量 | 需要学习协程概念 |
RxJava Schedulers | 丰富的操作符支持 | 增加包大小 |
八、常见问题解决方案
8.1 线程池阻塞问题
现象:任务堆积导致ANR
kotlin
// 错误配置 - 无界队列
val badPool = ThreadPoolExecutor(
4, 4, 0L, TimeUnit.SECONDS,
LinkedBlockingQueue() // 危险!
)
// 正确方案 - 使用有界队列
val safePool = ThreadPoolExecutor(
4, 16, 60L, TimeUnit.SECONDS,
ArrayBlockingQueue(100), // 有界
RejectedExecutionHandler { r, _ ->
Log.w("Pool", "Task rejected: $r")
}
)
8.2 上下文切换优化
kotlin
// 根据设备核心数动态配置
val optimalThreads = max(2, Runtime.getRuntime().availableProcessors() - 1)
val optimizedPool = Executors.newFixedThreadPool(optimalThreads)
九、版本兼容性说明
API Level | 关键变化 |
---|---|
Android 3.0+ | 引入多核优化 |
Android 8.0+ | 后台执行限制 |
Android 10+ | 严格模式检测线程阻塞 |
Android 11+ | 限制访问非SDK接口的Executor实现 |
总结建议
-
简单场景 :直接使用
Executors
预置线程池kotlinval ioPool = Executors.newFixedThreadPool(4)
-
精细控制 :实现自定义
Executor
kotlinclass CustomExecutor : Executor { ... }
-
Android最佳实践:
- 避免在主线程执行耗时操作
- 使用
Lifecycle
感知的执行器 - 对CPU密集型任务限制线程数
-
现代替代方案:
kotlin// 协程方式 val scope = CoroutineScope(Dispatchers.IO) scope.launch { /* 后台任务 */ }
正确选择执行策略可以显著提升应用性能和响应速度,同时避免内存泄漏和ANR问题。
更多分享
- Android跨进程通信中的关键字详解:in、out、inout、oneway
- 一文带你吃透Kotlin协程的launch()和async()的区别
- Kotlin 委托与扩展函数------新手入门
- Kotlin 作用域函数(let、run、with、apply、also)的使用指南
- 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
- Kotlin 扩展方法(Extension Functions)使用详解
- Kotlin 中 == 和 === 的区别
- Kotlin 操作符与集合/数组方法详解------新手指南
- Kotlin 中 reified 配合 inline 不再被类型擦除蒙蔽双眼
- Kotlin Result 类型扩展详解 ------ 新手使用指南