如何同步协程?

J_S*_*ton 10 android kotlin kotlin-coroutines

我试图确保这两种方法是同步的。我注意到协程比线程更难同步。我怎么能保证如果我调用start()然后stop()我的代码实际上会在最后停止?

object Test {

    private val coroutine = CoroutineScope(Dispatchers.IO)

    @Synchronized
    fun start() {
        coroutine.launch {
            // some work
        }
    }

    @Synchronized
    fun stop() {
        coroutine.launch {
            // clean up then stop
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我担心的是我start()当时打电话stop()但实际上先停止执行。所以我的代码在它应该停止的时候继续。

i30*_*mb1 8

命令的同步或顺序执行是两件不同的事情。
如果您需要执行“开始”然后“停止”,只需不要使用您的“coroutine.launch”创建新的协程,而是为您的函数使用 suspend 关键字,然后像这样执行它们:

suspend fun start() {}

suspend fun stop() {}

fun main() {
    scope.launch {
        start()
        stop()
    }
}
Run Code Online (Sandbox Code Playgroud)

但是如果你想同步两种方法,你可以阅读官方 Kotlin 共享可变状态指南,其中提供了一些很好的解决方案。并做一些这样的思考:

val mutex = Mutex()

fun main() {
    mutex.withLock {
        start()
        stop()
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的第二个例子不起作用,因为“Mutex.withLock”是一个“挂起”的乐趣,并且也需要在“挂起”函数内运行 (3认同)

omz*_*990 0

使用Deferred带有布尔值的作业,然后使用await()它来等待完成。像这样的东西:

fun doSomeWork() {
    GlobalScope.launch(Dispatchers.Main) {
        val isStartingComplete = start().await()
        // await() will wait for the completion of the start() function
        if (isStartingComplete) {
            stop()
        }
    }
}

fun start(): Deferred<Boolean> {
    return GlobalScope.async (Dispatchers.IO) {
        // Do your start work
        true
    }
}

fun stop() {
    // Do your stop work
}
Run Code Online (Sandbox Code Playgroud)