【问题标题】:Does a delay in one coroutine job affect another?一项协程工作的延迟会影响另一项协程工作吗?
【发布时间】:2021-07-22 20:23:22
【问题描述】:

根据文档,延迟会挂起协程但不会阻塞线程:

延迟是一种特殊的暂停功能。它将协程暂停特定时间。挂起协程不会阻塞底层线程,但允许其他协程运行并使用底层线程的代码。

但是在运行此代码时:

fun main() {

    println("1")
    GlobalScope.launch {
        doSomething()
        delay(1000L)
        println("3")
    }
    GlobalScope.launch {
        delay(1000L)
        println("4")
    }
    println("5")
}

suspend fun doSomething() {

    delay(500L)
    println("2")
    delay(1000L)
}

给出的输出是:

1
5
2
4
3 

根据我的理解,它应该显示1 5 4 2 3。 这是因为doSomething() 在第一个协程中被调用,因此与第二个协程相比延迟更多,并且第二个协程被异步调用。我的误会在哪里?

同样使用这段代码,两个值会在 2 秒后打印在一起:

fun main() {

    GlobalScope.launch {

        val value1 = doSomething1()
        val value2 = doSomething2()
        println(value1)
        println(value2)
    }
}

suspend fun doSomething1(): String {

    delay(1000L)
    return "This is the answer1"
}

suspend fun doSomething2(): String {

    delay(1000L)
    return "This is the answer2"
}

这是为什么?

【问题讨论】:

    标签: multithreading kotlin kotlin-coroutines


    【解决方案1】:

    TL;DR

    不,不同工作的延迟不会相互影响。


    对于您的第一个问题,显然 1 和 5 是第一个和最后一个,因此我们可以忽略它们。所以对于其他人,我们有:

    Print Delays Total delay
    2 500 500
    3 500, 1000, 1000 2500
    4 1000 1000

    所以顺序将是 2、4、3,您已通过输出验证。

    如果你想更多地了解协程是如何运行的,我们可以考虑每个作业在大致每个时间步发生了什么:

    Time Job 1 Job 2
    0 delay(500L) delay(1000L)
    500 print("2"); delay(1000L) -
    1000 - print("4")
    1500 delay(1000L) -
    2000 - -
    2500 print("3") -

    要解决你的第二个问题,你可以把它写成一段代码:

    GlobalScope.launch {
    
        delay(1000L)
        val value1 = "This is the answer1"
        delay(1000L)
        val value2 = "This is the answer2"
        println(value1)
        println(value2)
    }
    

    很明显,打印语句会一个接一个地运行。仅仅因为获取值存在延迟,并不意味着打印它们之间存在延迟。如果 print 语句位于两个 doSomething 方法中,我认为您所期望的行为将会发生。

    【讨论】:

    • 这是否意味着2不会受到协程延迟的影响,而只会受到suspend函数中它之前的延迟的影响?
    • 在2之前只有一个延迟,即doSomething中的500。您指的其他延迟是什么?
    • 挂起函数中2后的1000延迟和协程中的1000延迟
    • 挂起函数中的 1000 延迟和协程中的 1000 延迟(我猜你指的是第一次启动?)是 after Log.d(TAG, "2")。所以他们不会影响那个声明
    • 更新了我的答案。
    【解决方案2】:
    so the delay is more as compared to the second coroutine
    

    不,第一个延迟是:500L, 第二个延迟是:1000L

    【讨论】:

    • 是不是表示2不会受到协程集体延迟的影响?
    猜你喜欢
    • 2020-09-15
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多