编写一个类似于线程池,能够管理任务的协程池
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import java.util.concurrent.ConcurrentLinkedQueue
data class UploadTask(val position: Int, val task: suspend () -> Unit, var job: Job? = null)
class CoroutinePoolManager(poolSize: Int) {
private val semaphore = Semaphore(poolSize)
private val coroutineScope = CoroutineScope(Dispatchers.IO)
private val taskQueue = ConcurrentLinkedQueue<UploadTask>()
private val runQueue = ConcurrentLinkedQueue<UploadTask>()
private val lock = Mutex()
init {
repeat(poolSize) {
coroutineScope.launch {
while (true) {
if (taskQueue.isNotEmpty()) {
semaphore.acquire()
try {
var task: UploadTask?
lock.withLock {
task = taskQueue.poll()
if (task != null) {
task?.job = coroutineScope.launch {
task?.task?.invoke()
}
runQueue.add(task)
}
}
if (task != null && task?.job?.isCancelled == false) {
task?.job?.join()
}
} finally {
semaphore.release()
}
} else {
delay(200)
}
}
}
}
}
fun submit(position: Int, task: suspend () -> Unit) {
taskQueue.add(UploadTask(position, task))
}
/**
* 删除指定任务
*/
suspend fun cancelTask(position: Int) {
lock.withLock {
taskQueue.find { it.position == position }
val task = runQueue.find { it.position == position }
task?.job?.cancel()
}
}
fun shutdownAll() {
coroutineScope.cancel()
taskQueue.clear()
runQueue.clear()
}
}