Kotlin Coroutines

https://kotlinlang.org/docs/coroutines-overview.html

协程是作为三方库进行提供的,类似 javax

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <kotlin.code.style>official</kotlin.code.style>
    <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
    <coroutines.version>1.7.3</coroutines.version>
    <kotlin.version>2.2.0</kotlin.version>
</properties>


<dependencies>
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-test-junit5</artifactId>
        <version>2.2.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.0</version>
        <scope>test</scope>
    </dependency>
    <!-- Kotlin 标准库 -->
    <dependency>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-stdlib</artifactId>
        <version>${kotlin.version}</version>
    </dependency>
    <!-- Kotlin 协程核心 -->
    <dependency>
        <groupId>org.jetbrains.kotlinx</groupId>
        <artifactId>kotlinx-coroutines-core</artifactId>
        <version>${coroutines.version}</version>
    </dependency>
    <!-- Kotlin 协程 JDK8 支持 -->
    <dependency>
        <groupId>org.jetbrains.kotlinx</groupId>
        <artifactId>kotlinx-coroutines-jdk8</artifactId>
        <version>${coroutines.version}</version>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.jetbrains.kotlinx</groupId>
        <artifactId>kotlinx-coroutines-test</artifactId>
        <version>${coroutines.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

基本使用

协程的创建和执行流程

  1. 协程创建:通过 launch 或 async 创建协程

  2. 调度器分配:根据指定的调度器决定执行线程

  3. 挂起函数调用:遇到挂起函数时保存当前状态

  4. 线程释放:挂起时释放线程,供其他协程使用

  5. 恢复执行:挂起操作完成后恢复协程执行

launch - 不需要返回结果

import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val job: Job = launch {
        // 协程体
        delay(1000L)
        println("World!")
    }
    println("Hello,")
    job.join() // 等待协程完成
}

async - 需要返回结果

import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    val deferred: Deferred<Int> = async {
        // 执行计算并返回结果
        delay(1000L)
        42
    }

    val result = deferred.await() // 等待并获取结果
    println("Result: $result") // 42
}

runBlocking - 桥接阻塞代码和协程

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    runBlocking {
        // 在这个块内,协程会阻塞当前线程
        launch {
            delay(1000L)
            println("Inside runBlocking")
        }
    }
    println("After runBlocking")
}

协程作用域 CoroutineScope

协程上下文 CoroutineContext

import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() = runBlocking {
    // 自定义上下文
    val customContext = Dispatchers.IO + CoroutineName("MyCoroutine") + SupervisorJob()

    launch(customContext) {
        println("Running in thread: ${Thread.currentThread().name}")
        println("Coroutine name: ${coroutineContext[CoroutineName]?.name}")
    }.join()
}

挂起函数 Suspend Functions

使用 suspend 关键字修饰的函数即为挂起函数

suspend fun myFunc()

调度器 Dispatchers

import kotlinx.coroutines.withContext

suspend fun demonstrateDispatchers() {
    // Dispatchers.Main - Android主线程
    withContext(Dispatchers.Main) {
        // 更新UI
    }

    // Dispatchers.IO - 用于磁盘和网络IO
    withContext(Dispatchers.IO) {
        // 文件操作、网络请求
    }

    // Dispatchers.Default - 用于CPU密集型任务
    withContext(Dispatchers.Default) {
        // 复杂计算、排序、处理大量数据
    }

    // Dispatchers.Unconfined - 不限制在任何特定线程
    withContext(Dispatchers.Unconfined) {
        // 在调用者线程开始,在恢复时的线程继续
    }
}

异常处理

通道 (Channel) 和流 (Flow)

Channel - 协程间的通信

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main(): Unit = runBlocking {
    val channel = Channel<Int>()

    // 生产者
    launch {
        for (x in 1..5) {
            channel.send(x * x)
            delay(100L)
        }
        channel.close() // 关闭通道
    }

    // 消费者
    launch {
        for (y in channel) {
            println("Received: $y")
        }
    }
}

Flow - 异步数据流

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map

class FlowExample {
    fun simpleFlow(): Flow<Int> = flow {
        // 流构建器
        for (i in 1..3) {
            delay(100L)
            emit(i) // 发射值
        }
    }

    suspend fun collectFlow() {
        simpleFlow()
            .map { it * it } // 转换
            .filter { it % 2 != 0 } // 过滤
            .collect { value -> // 收集
                println("Collected: $value")
            }
    }

    // 状态流
    private val _state = MutableStateFlow(0)
    val state: StateFlow<Int> = _state.asStateFlow()

    // 共享流
    private val _events = MutableSharedFlow<Int>()
    val events: SharedFlow<Int> = _events.asSharedFlow()
}

结构化并发

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

fun structuredConcurrencyExample() {
    val scope = CoroutineScope(Job())
    
    scope.launch {
        // 父协程
        launch {
            // 子协程1
            delay(1000L)
            println("Child 1 completed")
        }
        
        launch {
            // 子协程2
            delay(2000L)
            println("Child 2 completed")
        }
    }
    
    // 取消父协程会自动取消所有子协程
    Thread.sleep(500L)
    scope.cancel() // 所有子协程都会被取消
}
posted @ 2025-11-14 21:14  vonlinee  阅读(7)  评论(0)    收藏  举报