Kotlin协程挂起和恢复

一、delay实现定时挂起

二、通过条件变量和锁

在 Kotlin 协程中,你可以通过 kotlinx.coroutines.sync 模块提供的 Mutex 和 ConditionVariable 来实现条件变量式的挂起与恢复。

步骤:

创建 Mutex 和 ConditionVariable 对象:

import kotlinx.coroutines.sync.*

val mutex = Mutex()
val condition = ConditionVariable()
在需要挂起的协程中获取 Mutex 并等待 ConditionVariable:

import kotlinx.coroutines.*

suspend fun mySuspendFunction() {
    mutex.withLock {
        println("mySuspendFunction 准备挂起")
        condition.await() // 等待条件变量
        println("mySuspendFunction 已恢复")
    }
}
在其他协程中触发 ConditionVariable 唤醒挂起的协程:

launch {
    delay(1000) // 等待 1 秒
    mutex.withLock {
        condition.signal() // 唤醒挂起的协程
        println("已唤醒挂起的协程")
    }
}
完整示例:

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.*

fun main() = runBlocking<Unit> {
    val mutex = Mutex()
    val condition = ConditionVariable()

    launch {
        mutex.withLock {
            println("协程 1 准备挂起")
            condition.await() // 等待条件变量
            println("协程 1 已恢复")
        }
    }

    launch {
        delay(1000) // 等待 1 秒
        mutex.withLock {
            condition.signal() // 唤醒协程 1
            println("已唤醒协程 1")
        }
    }

    // 等待协程 1 完成
    delay(2000)
}
解释:

Mutex 保证了对 ConditionVariable 的操作是线程安全的。
condition.await() 会在 Mutex 锁定状态下挂起当前协程,直到 condition.signal() 被调用。
condition.signal() 会唤醒所有在该 ConditionVariable 上等待的协程。
注意:

ConditionVariable 只能在 Mutex 锁定状态下使用。
signal() 方法会唤醒所有等待的协程,如果需要唤醒特定协程,可以使用 signalAll() 方法。
确保在 await() 之前获取 Mutex 锁,并在 signal() 之后释放锁,以防止死锁。

三、通过CountDownLatch计数器来挂起和恢复

在 Kotlin 协程中,你可以使用 kotlinx.coroutines.sync.CountDownLatch 来实现类似于条件变量的挂起与恢复机制,但 CountDownLatch 更加偏向于计数器式的等待,而不是条件式的等待。

步骤:

创建 CountDownLatch 对象:

import kotlinx.coroutines.sync.*

val latch = CountDownLatch(1)
在需要挂起的协程中调用 latch.await():

import kotlinx.coroutines.*

suspend fun mySuspendFunction() {
    println("mySuspendFunction 准备挂起")
    latch.await() // 等待计数器减到 0
    println("mySuspendFunction 已恢复")
}
在其他协程中调用 latch.countDown() 来减少计数器:

launch {
    delay(1000) // 等待 1 秒
    latch.countDown() // 减少计数器
    println("已唤醒挂起的协程")
}
完整示例:

import kotlinx.coroutines.*
import kotlinx.coroutines.sync.*

fun main() = runBlocking<Unit> {
    val latch = CountDownLatch(1)

    launch {
        println("协程 1 准备挂起")
        latch.await() // 等待计数器减到 0
        println("协程 1 已恢复")
    }

    launch {
        delay(1000) // 等待 1 秒
        latch.countDown() // 减少计数器
        println("已唤醒挂起的协程")
    }

    // 等待协程 1 完成
    delay(2000)
}
解释:

CountDownLatch 初始化时指定一个计数器初始值。
latch.await() 会挂起当前协程,直到计数器减到 0。
latch.countDown() 会减少计数器的值。
区别于条件变量:

CountDownLatch 是计数器式的,当计数器减到 0 时,所有等待的协程会被唤醒。
ConditionVariable 是条件式的,只有当满足特定条件时才会唤醒等待的协程。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值