You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin协程调用Thread.sleep()无法并行执行的问题解决

Kotlin协程并行执行问题解决

问题描述

作为Kotlin协程初学者,编写了一个尝试并行执行的示例,但代码未按预期并行运行。需求如下:

  • 改造sleepTwoSec()方法,使其在launch{...}中调用时实现并行执行
  • 无需返回值(即发即弃),但launchMultipleParallelFuns()需等待所有launch启动的任务完成后再退出

原代码如下:

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.lang.Thread.sleep
import kotlin.time.measureTime

fun main() {
    println("main start")
    println(measureTime { blockingFunction() })
    println("main end")
}

fun blockingFunction() = runBlocking {
    println("  start blockingFunction")
    launchMultipleParallelFuns()
    println("  end blockingFunction")
}

suspend fun launchMultipleParallelFuns() = coroutineScope {
    println("    start launchMultipleParallelFuns")
    launch { sleepTwoSec(1) }
    launch { sleepTwoSec(2) }
    launch { sleepTwoSec(3) }
    launch { sleepTwoSec(4) }
    println("    end launchMultipleParallelFuns")
}

fun sleepTwoSec(n: Int) {
    println("      start sleepTwoSec $n")
    sleep(2000)
    println("      end sleepTwoSec $n")
}

实际输出

main start
  start blockingFunction
    start launchMultipleParallelFuns
    end launchMultipleParallelFuns
      start sleepTwoSec 1
      end sleepTwoSec 1
      start sleepTwoSec 2
      end sleepTwoSec 2
      start sleepTwoSec 3
      end sleepTwoSec 3
      start sleepTwoSec 4
      end sleepTwoSec 4                     // 无并行执行
  end blockingFunction
8.135047100s                                // 总耗时约8秒,无并行
main end

预期输出

main start
  start blockingFunction
    start launchMultipleParallelFuns
    end launchMultipleParallelFuns           // 符合预期
      start sleepTwoSec 1                    // 所有任务同时启动
      start sleepTwoSec 2
      start sleepTwoSec 3
      start sleepTwoSec 4
      end sleepTwoSec 1
      end sleepTwoSec 2
      end sleepTwoSec 3
      end sleepTwoSec 4
  end blockingFunction
2s                                           // 总耗时约2秒
main end

尝试过的无效修改

曾尝试用suspendCoroutine将sleepTwoSec改为挂起函数,但结果依旧:

suspend fun sleepTwoSec(n: Int) = suspendCoroutine {
    println("      start sleepTwoSec $n")
    sleep(2000)
    println("      end sleepTwoSec $n")
    it.resume(Unit)
}

问题原因

  • Thread.sleep(2000)是阻塞式操作,会占用当前线程的执行时间片,协程调度器无法切换到其他协程执行
  • 即使将方法改为挂起函数,内部仍调用阻塞的sleep,依旧会阻塞协程所在的线程,导致所有launch任务串行执行

解决方案

有两种可行方案,核心都是避免阻塞协程调度线程:

方案1:使用协程非阻塞挂起函数delay()

直接替换Thread.sleep()为Kotlin协程提供的delay(),这是一个非阻塞的挂起函数,会释放线程让其他协程执行:

import kotlinx.coroutines.delay

suspend fun sleepTwoSec(n: Int) {
    println("      start sleepTwoSec $n")
    delay(2000) // 非阻塞挂起
    println("      end sleepTwoSec $n")
}

方案2:将阻塞操作放到IO调度器执行

如果必须使用阻塞的sleep(或其他阻塞IO操作),可以用withContext(Dispatchers.IO)将任务切换到IO线程池执行,避免阻塞主线程/协程调度线程:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

suspend fun sleepTwoSec(n: Int) = withContext(Dispatchers.IO) {
    println("      start sleepTwoSec $n")
    sleep(2000) // 阻塞操作在IO线程执行
    println("      end sleepTwoSec $n")
}

修改后的完整代码(以方案1为例)

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.time.measureTime

fun main() {
    println("main start")
    println(measureTime { blockingFunction() })
    println("main end")
}

fun blockingFunction() = runBlocking {
    println("  start blockingFunction")
    launchMultipleParallelFuns()
    println("  end blockingFunction")
}

suspend fun launchMultipleParallelFuns() = coroutineScope {
    println("    start launchMultipleParallelFuns")
    launch { sleepTwoSec(1) }
    launch { sleepTwoSec(2) }
    launch { sleepTwoSec(3) }
    launch { sleepTwoSec(4) }
    println("    end launchMultipleParallelFuns")
}

suspend fun sleepTwoSec(n: Int) {
    println("      start sleepTwoSec $n")
    delay(2000)
    println("      end sleepTwoSec $n")
}

验证结果

修改后执行输出符合预期,总耗时约2秒,所有sleepTwoSec任务并行启动并执行。

内容的提问来源于stack exchange,提问作者Irina S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 10:25:20