ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Kotlin : Coroutines 协程—简单应用

2026/9/10 13:42:17 拓冰建站 浏览量
Kotlin : Coroutines 协程—简单应用

介绍:

Kotlin Coroutines 是一种用于简化异步代码的并发设计模式。它基于协程的概念,允许在单个线程上挂起和恢复执行,从而管理长时间运行的任务。协程类似于线程,但不绑定到特定的线程,可以在一个线程中挂起其执行,并在另一个线程中恢复。

Kotlin Coroutines 的特点包括:

  1. 轻量级:协程可以在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多个并行操作。
  2. 内存泄漏更少:使用结构化并发机制在一个作用域内执行多项操作。
  3. 内置取消支持:取消操作会自动在运行中的整个协程层次结构内传播。
  4. Jetpack 集成:许多 Jetpack 库都包含提供全面协程支持的扩展。某些库还提供自己的协程作用域,可供用于结构化并发。

在使用 Kotlin Coroutines 时,开发人员需要了解协程的生命周期,以便正确地控制协程的挂起和恢复。理论上,由于协程不涉及操作系统调度,因此在用户态上进行操作,而线程需要经历用户态与内核态之间的切换,所以协程性能更佳。然而,不同的语言在实现上可能存在差异,例如 Kotlin 协程的底层实现存在线程切换,因此异步任务可能执行在另一条线程上。

总之,Kotlin Coroutines 是一种轻量级、高效的并发编程工具,适用于处理异步任务和长时间运行的操作。通过使用协程,开发人员可以简化代码结构并更好地管理并发执行。

导包

导包网站:        https://mvnrepository.com/

dependencies {...//加入2个
// https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-coreimplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")// https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-androidruntimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")}

1.launch 异步 不阻塞线程

package org.exampleimport kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.system.measureTimeMillis/**** Coroutines 协程* 轻量级线程* 生命周期控制* 阻塞 非阻塞* var* val* const val*/
class CoroutinesTest {/*** CoroutineScope* GlobalScope.launch  异步 不阻塞线程* 返回 Job 用于控制协程 取消协程...* 一个可以用来创建子执行上下文的方法。你可以用它来启动一个新的执行上下文,该上下文可以在异步任务中独立运行,而不会影响应用的其他部分* 用途 :用于创建新的执行上下文,这些上下文可以独立运行,用于执行需要独立生命周期的异步任务。* 生命周期:创建的执行上下文具有自己的生命周期,你可以在需要时启动和停止它。* 并发性:创建的执行上下文也可以并发运行,但它更加灵活,可以用于更细粒度的控制* 取消:创建的执行上下文可以通过调用 Isolate.kill() 方法来停止* 性能和资源使用:允许创建独立的执行上下文,这可以更好地控制资源和性能,特别是在需要并发处理大量任务时。* 隔离性:创建的执行上下文是隔离的,这有助于避免不同任务之间的冲突和相互影响。* 错误处理:错误处理方式更加灵活,可以通过捕获异常或使用其他错误处理机制来处理。*/@OptIn(DelicateCoroutinesApi::class)fun testLaunch() {val time: Long = measureTimeMillis {GlobalScope.launch {Thread.sleep(1000)println("testLaunch 中的  GlobalScope.launch 线程${Thread.currentThread()} hi hellow")}GlobalScope.launch {Thread.sleep(1000)println("testLaunch 中的  GlobalScope.launch2 线程${Thread.currentThread()} hi hellow 第二个")}//停一下等待 上面线程执行完成Thread.sleep(2200)println("我是最下面的数据")}println("函数总耗时:$time")}
}fun main() {val ff = coroutinesTest();ff.testLaunch();
}

运行结果:

testLaunch 中的  GlobalScope.launch2 线程Thread[DefaultDispatcher-worker-2,5,main] hi hellow 第二个
testLaunch 中的  GlobalScope.launch 线程Thread[DefaultDispatcher-worker-1,5,main] hi hellow
我是最下面的数据
函数总耗时:2426

2.async异步,不阻塞线程

/*** CoroutineScope* GlobalScope.async 异步 不阻塞线程* 返回 Deferred<T> 返回一个 Future 对象,该对象在全局执行上下文中运行。这意味着它将在应用的整个生命周期中运行,不受应用上下文(如生命周期方法)的影响。* 用途 :主要用于创建全局的异步任务,这些任务在应用的整个生命周期中运行* 生命周期:与应用的生命周期相同,除非你明确地取消了它* 并发性:允许你创建全局的异步任务,这些任务可以在应用的整个生命周期中并发运行* 取消:Future 对象可以通过调用 Future.cancel() 方法来取消* 性能和资源使用:在全局执行上下文中运行,所以可能会影响应用的性能和资源使用。特别是当有大量全局异步任务时,这可能会成为一个问题* 隔离性:在全局执行上下文中运行的,因此没有隔离性。这意味着不同的异步任务可以相互影响* 错误处理:错误可以通过 Future 的异常处理机制来处理*/fun testAsync() {val time: Long = measureTimeMillis {GlobalScope.async {Thread.sleep(1000)println("testLaunch 中的  GlobalScope.async 线程${Thread.currentThread()} hi hellow")}GlobalScope.async {Thread.sleep(1000)println("testLaunch 中的  GlobalScope.async2 线程${Thread.currentThread()} hi hellow 第二个")}//停一下等待 上面线程执行完成Thread.sleep(2200)println("我是最下面的数据")}println("函数总耗时:$time")}

运行结果:

testLaunch 中的  GlobalScope.async 线程Thread[DefaultDispatcher-worker-1,5,main] hi hellow
testLaunch 中的  GlobalScope.async2 线程Thread[DefaultDispatcher-worker-2,5,main] hi hellow 第二个
我是最下面的数据
函数总耗时:2487

3.runBlocking 阻塞线程

/***runBlocking ,阻塞线程* 顺序执行*/fun testRunBlocking(){val time = measureTimeMillis {runBlocking {println("testRunBlocking 中的  runBlocking 线程${Thread.currentThread()} hi hellow")Thread.sleep(2000)println("testRunBlocking 中的  runBlocking2 线程${Thread.currentThread()} hi hellow 第二个")//延迟 毫秒delay(3000)}println("我是外面的数据")}println("函数总耗时:$time")}

运行结果:

testRunBlocking 中的  runBlocking 线程Thread[main,5,main] hi hellow
testRunBlocking 中的  runBlocking2 线程Thread[main,5,main] hi hellow 第二个
我是外面的数据
函数总耗时:5194

4.cancel  和  join

 /***runBlocking 会等待内部协程执行完毕才结束*/fun testCancelJoin() = runBlocking {val time = measureTimeMillis {// launch 异步不阻塞val jobL1: Job = launch {println("testCancelJoin 中的 jobL1 launch1 线程${Thread.currentThread()} hi hellow")}// Jobval jobL2: Job = launch {println("testCancelJoin 中的 jobL2 launch2 线程${Thread.currentThread()} hi hellow 第二个")}//取消jobL2协程执行.jobL2.cancel()//jobL2,并返回主协程
//            jobL2.cancelAndJoin()//Deferred<T>   async 异步不阻塞val defA1: Deferred<Unit> = async {//repeat 执行指定次数的给定函数操作。//当前迭代的从零开始的索引作为参数传递给操作。repeat(10) {println("testCancelJoin 中的defA1  async1 线程${Thread.currentThread()} $it hi hellow")delay(200)}}// //取消defA1协程
//            defA1.cancel()//取消defA1协程,并返回主协程
//            defA1.cancelAndJoin()//需要等待 defA1 协程执行结束 才会执行下面代码defA1.join()val defA2: Deferred<Unit> = async {println("testCancelJoin 中的defA2  async2 线程${Thread.currentThread()} hi hellow")}println("我是外面的数据 线程${Thread.currentThread()}")}println("函数总耗时:$time")
}

运行结果:

testCancelJoin 中的 jobL1 launch1 线程Thread[main,5,main] hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 0 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 1 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 2 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 3 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 4 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 5 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 6 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 7 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 8 hi hellow
testCancelJoin 中的defA1  async1 线程Thread[main,5,main] 9 hi hellow
我是外面的数据 线程Thread[main,5,main]
函数总耗时:2506
testCancelJoin 中的defA2  async2 线程Thread[main,5,main] hi hellow

5.withTimeout

/** runBlocking 阻塞的* withTimeout 超时自动取消内部协程*/fun testTimeOut() = runBlocking {val time = measureTimeMillis {//超时自动取消内部协程 会抛出异常withTimeout(3000) {//repeat 执行指定次数的给定函数操作。//当前迭代的从零开始的索引作为参数传递给操作。repeat(200) {println("withTimeout repeat当前迭代的线程 ${Thread.currentThread()} -- $it")delay(300)}println("withTimeout 的线程 ${Thread.currentThread()} ")}//超时自动取消内部协程 不会抛出异常
//            withTimeoutOrNull(2000){
//                repeat(200){
//                    println("withTimeoutOrNull repeat当前迭代的线程 ${Thread.currentThread()} -- $it")
//                    delay(300)
//                }
//            }}}

运行结果:

withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 0
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 1
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 2
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 3
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 4
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 5
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 6
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 7
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 8
withTimeout repeat当前迭代的线程 Thread[main,5,main] -- 9
Exception in thread "main" kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 3000 msat kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:184)at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:154)at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.common.kt:508)at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:108)at java.base/java.lang.Thread.run(Thread.java:833)

6.await

    /**runBlocking 阻塞的 等待协程执行完毕 这个方法才会结束* await() 拿结果* getCompleted()   拿结果*/fun testAwait() = runBlocking {val time = measureTimeMillis {//Deferred<T>   async 异步不阻塞val defA1: Deferred<Int> = async {println("testAwait 中的defA1  async1 线程${Thread.currentThread()} hi hellow")delay(2000)//延迟2秒100}
//            defA1.join()val defA2: Deferred<String> = async {println("testAwait 中的defA2  async2 线程${Thread.currentThread()} hi hellow")
//                delay(3000)//延迟3秒
//                "hi hello"//调用挂起方法getData()}
//            defA2.join()println("结果:线程${Thread.currentThread()} --- ${defA1.await()}  --${defA2.await()} ")
//            println("结果:线程${Thread.currentThread()} --- ${defA1.getCompleted()}  --${defA2.getCompleted()} ")}println("函数总耗时:$time")}// 声明一个 suspend 方法  挂起方法suspend fun getData(): String {println("testAwait 中的 getData()线程${Thread.currentThread()} hi hellow")delay(1000) // 模拟一个长时间运行的操作return "Hello, World!"}

运行结果:

testAwait 中的defA1  async1 线程Thread[main,5,main] hi hellow
testAwait 中的defA2  async2 线程Thread[main,5,main] hi hellow
testAwait 中的 getData()线程Thread[main,5,main] hi hellow
结果:线程Thread[main,5,main] --- 100  --Hello, World! 
函数总耗时:2131