线程区别
线程同步的:run
和runCatching
是同步的- 线程异步的:
runBlocking
和runInterruptible
是异步的。
run
和 runCatching
是 Kotlin 标准库的一部分,可以在所有支持的平台上使用。
runBlocking
和 runInterruptible
是 Coroutines 协程的一部分。
Run 作用域函数
对象调用它,作用域内可以直接访问该对象的属性和方法, 省略this
。
另外, run
可以返回一个结果,这个结果可以在后续的步骤中使用。
val event = Event(id = UUID.randomUUID(), value = 10, message = null)
val isEven = event
.run {
value % 2 == 0
}
run
和 apply
有什么区别呢?
主要的区别在于他们的返回值,apply
总是返回对象本身,这对于链式对象配置非常好。
RunCatching 作用域函数
runCatching
实际上是 run加
一个 try...catch
块。
val result = event.runCatching {
value / 0 //错误代码
}.onFailure {
println("We failed to divide by zero. Throwable: $it")
}.onSuccess {
println("Devision result is $it")
}
优势:
- 块执行的失败或成功的结果可以用链式的处理;
- 拿到这个错误的变量在流中抛出。
RunBlocking 作用域函数
使用它可以开启一个协程,但是会阻塞了当前的线程。
使用 runBlocking 很容易失去对异步操作的跟踪,并失去用于自动管理挂起和切换要执行的协程的强大协程功能。实际开发中不推荐使用,在移动应用程序开发中它主要用于单元测试。
RunInterruptible 作用域函数
它可以用于在一个可中断的上下文中运行代码块。它是在Kotlin 1.5版本中引入的一个新特性。
使用RunInterruptible可以在代码块中处理可能被中断的操作,例如长时间运行的任务或者需要等待外部事件的操作。它提供了一种简洁的方式来处理这些情况,而不需要显式地处理线程中断。
具体来说,RunInterruptible函数类型接受一个lambda表达式作为参数,并返回一个可中断的结果。在lambda表达式中,你可以执行需要中断的操作,并使用`yield()`函数来检查是否有中断请求。如果有中断请求,你可以选择在适当的时候退出代码块。
以下是一个使用RunInterruptible的示例:
import kotlinx.coroutines.runInterruptible
fun main() {
runInterruptible {
// 执行可能被中断的操作
for (i in 1..10) {
println("Processing $i")
Thread.sleep(1000)
yield() // 检查是否有中断请求
}
}
}
在上面的示例中,我们使用了`runInterruptible`函数来运行一个可能被中断的操作。在lambda表达式中,我们使用了`yield()`函数来检查是否有中断请求,并在每次循环迭代之后暂停1秒钟。