实现工具类
package com.lujianfei.composeui.utils
/**
* Author: lujianfei
* Date: 2024/5/27 11:57
* Description:
*/
import android.util.Log
import java.util.ArrayDeque
import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.BlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
class ThreadPool private constructor() {
companion object {
/**
* 系统最大可用线程
*/
private val CPU_AVAILABLE = Runtime.getRuntime().availableProcessors()
/**
* 最大线程数
*/
private val MAX_POOL_COUNTS = CPU_AVAILABLE * 2 + 1
/**
* 线程存活时间
*/
private const val AVAILABLE = 1L
/**
* 核心线程数
*/
private val CORE_POOL_SIZE = CPU_AVAILABLE + 1
val instance by lazy { ThreadPool() }
}
private var mActive: Runnable? = null
/**
* java线程池
*/
private var threadPoolExecutor: ThreadPoolExecutor?
/**
* 线程池缓存队列
*/
private val mWorkQueue: BlockingQueue<Runnable> = ArrayBlockingQueue(CORE_POOL_SIZE)
private val mArrayDeque = ArrayDeque<Runnable>()
init {
threadPoolExecutor = ThreadPoolExecutor(
CORE_POOL_SIZE,
MAX_POOL_COUNTS,
AVAILABLE,
TimeUnit.SECONDS,
mWorkQueue
)
}
/**
* 并行线程
*/
fun addParallelTask(runnable: Runnable?) {
if (runnable == null) {
throw NullPointerException("addParallelTask(Runnable runnable)传入参数为空")
}
threadPoolExecutor?.let { threadPoolExecutor->
if (threadPoolExecutor.activeCount < MAX_POOL_COUNTS) {
Log.i(
"Lee",
"目前有" + threadPoolExecutor.activeCount + "个线程正在进行中,有" + mWorkQueue.size + "个任务正在排队"
)
synchronized(this) { threadPoolExecutor.execute(runnable) }
}
}
}
/**
* 串行线程
*/
@Synchronized
fun addSerialTask(r: Runnable?) {
if (r == null) {
throw NullPointerException("addTask(Runnable runnable)传入参数为空")
}
mArrayDeque.offer(Runnable {
try {
r.run()
} finally {
scheduleNext()
}
})
// 第一次入队列时mActivie为空,因此需要手动调用scheduleNext方法
if (mActive == null) {
scheduleNext()
}
}
private fun scheduleNext() {
if (mArrayDeque.poll().also { mActive = it } != null) {
threadPoolExecutor?.execute(mActive)
}
}
fun stopThreadPool() {
threadPoolExecutor?.shutdown()
threadPoolExecutor = null
}
}
使用方法
ThreadPool.instance.addSerialTask {
// 需要执行的串行耗时任务
}
效果展示
这里为了 UI 实现方便,使用 Compose 编写示例
@Composable
private fun example1() {
val actions = remember {
mutableStateListOf<ThreadAction>()
}
Column {
Button(modifier = Modifier.padding(start = 15.dp), onClick = {
val currentAction = ThreadAction(label = "任务${actions.size + 1}").apply { status.value = ThreadStatus.Running }
actions.add(0, currentAction)
ThreadPool.instance.addSerialTask {
Thread.sleep(1000)
currentAction.status.value = ThreadStatus.Finished
}
}) {
Text(text = "新增任务")
}
LazyColumn {
items(actions) {
Text(text = "${it.label} ${it.status.value.label}", Modifier.padding(start = 15.dp, top = 5.dp))
}
}
}
}
data class ThreadAction(val label:String) {
val status = mutableStateOf(ThreadStatus.Running)
}
enum class ThreadStatus(val label:String) {
Running("正在执行"),
Finished("已完成")
}