Kotlin 协程四类 Dispatcher

Default: 默认情况下,此调度器使用的最大并行数等于 CPU 内核数,但至少为 2。 并行度 X 保证在这个调度器中并行执行的任务不超过 X 个。

Main: 不管是否已经在 main 线程中,都将会 Handler.post(block) 执行。

Main.immediate:如果已经在 main 线程中,将立即执行,否则将会 Handler.post(block) 执行。

override fun isDispatchNeeded(context: CoroutineContext): Boolean {
    return !invokeImmediately || Looper.myLooper() != handler.looper
}

IO: 与 Default 共享线程池,默认为 64 个线程的限制或内核数(以较大者为准)
用协程块 block 创建 Task 时,会标记 mode 为 TASK_PROBABLY_BLOCKING = 1。
添加 Task 后,会增加 blocking 任务数。
CPU线程数 = 已创建线程数 - blocking 任务数 cpuWorkers = (created - blocking)
如果 CPU线程数 < 核心线程数,则创建新的线程。

class CoroutineScheduler(
    val corePoolSize: Int,
    val maxPoolSize: Int,
    val idleWorkerKeepAliveNs: Long = IDLE_WORKER_KEEP_ALIVE_NS,
    val schedulerName: String = DEFAULT_SCHEDULER_NAME
) : Executor, Closeable

Kotlin 协程定义的线程池,对任务作了 CPU 任务和 Blocking 任务划分。

首先尝试将 Task 添加到当前线程的 localQueue 队列,如果添加失败,则添加到全局的 globalBlockingQueue 或 globalCpuQueue 队列。

val currentWorker = currentWorker()
val notAdded = currentWorker.submitToLocalQueue(task, tailDispatch)
if (notAdded != null) {
    if (!addToGlobalQueue(notAdded)) {
        // Global queue is closed in the last step of close/shutdown -- no more tasks should be accepted
        throw RejectedExecutionException("$schedulerName was terminated")
    }
}
private fun tryCreateWorker(state: Long = controlState.value): Boolean {
    val created = createdWorkers(state)
    val blocking = blockingTasks(state)
    val cpuWorkers = (created - blocking).coerceAtLeast(0)
    /*
     * We check how many threads are there to handle non-blocking work,
     * and create one more if we have not enough of them.
     */
    if (cpuWorkers < corePoolSize) {
        val newCpuWorkers = createNewWorker()
        // If we've created the first cpu worker and corePoolSize > 1 then create
        // one more (second) cpu worker, so that stealing between them is operational
        if (newCpuWorkers == 1 && corePoolSize > 1) createNewWorker()
        if (newCpuWorkers > 0) return true
    }
    return false
}

Unconfined:

withContext(Dispatchers.Unconfined) {
   println(1)
   withContext(Dispatchers.Unconfined) { // Nested unconfined
       println(2)
   }
   println(3)
}
println("Done")

可以打印“1 2 3”和“1 3 2”,这是一个可以更改的实现细节。但是可以保证只有当两个 withContext 都完成时才会打印“Done”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值