【问题标题】:Kotlin Coroutines sequential executionKotlin Coroutines 顺序执行
【发布时间】:2019-10-22 03:31:00
【问题描述】:

我正在尝试创建一个对象,它可以在自己的线程中按顺序执行一些任务,就像它是一个队列一样。

以下示例仅用于演示我的设置,可能完全错误。

class CoroutinesTest {
    fun a() {
        GlobalScope.launch {
            println("a started")
            delay(1000)
            println("a completed")
        }
    }

    fun b() {
        GlobalScope.launch {
            println("b started")
            delay(2000)
            println("b completed")
        }
    }

    fun complex() {
        a()
        b()
    }
}

fun main() {
    runBlocking {
        val coroutinesTest = CoroutinesTest()

        coroutinesTest.complex()

        delay(10000)
    }
}

现在这段代码打印以下内容

a started
b started
a completed
b completed

这意味着ab 并行执行。方法abcomplex 可以从不同的线程调用。当然,complex 方法也应该支持这个概念。现在,我需要一种允许我一次只执行一个任务的机制,所以我可以获得以下输出:

a started
a completed
b started
b completed

我做了一些研究,认为带有Channelactor 可以满足需要,但actor 现在被标记为已过时 (issue #87)。我不喜欢使用会发生变化的 API 的想法,所以我想以一种通用的方式来做这件事。

【问题讨论】:

  • 在 Kotlin 引入 actor 的替代品之前,没有通用的方法。我只是使用actor 并在新 API 出现时适应它。应该不会那么不同吧。或者你可以避开actor,直接使用Channel
  • 我同意——我使用演员,它非常适合您描述的确切用例。此外,您还可以为其封装一个状态(在 actor 内部声明 val 和 vars)作为奖励。

标签: kotlin kotlin-coroutines


【解决方案1】:

您可以通过MutexwithLock 调用来完成此操作。例如:

class CoroutinesTest {
    private val lock = Mutex()
    
    fun a() {
        GlobalScope.launch {
            lock.withLock {
                println("a started")
                delay(1000)
                println("a completed")
            }
        }
    }

    fun b() {
        GlobalScope.launch {
            lock.withLock {
                println("b started")
                delay(2000)
                println("b completed")
            }
        }
    }

    fun complex() {
        a()
        b()
    }
}

输出为

a started
a completed
b started
b completed

如果您想在一个范围内更好地控制执行顺序,您可以将工作与启动调用分开

class CoroutinesTest {
    private val lock = Mutex()
    
    suspend fun aImpl() {
        lock.withLock {
            println("a started")
            delay(1000)
            println("a completed")
        }
    }

    suspend fun bImpl() {
        lock.withLock {
            println("b started")
            delay(2000)
            println("b completed")
        }
    }

    fun a() {
        GlobalScope.launch { aImpl() }
    }

    fun b() {
        GlobalScope.launch { bImpl() }
    }

    fun complex() {
        GlobalScope.launch {
            aImpl()
            bImpl()
        }
    }
}

【讨论】:

    猜你喜欢
    • 2020-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 2019-10-14
    • 2019-11-28
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多