Kotlin 中的并发与多线程:高级进阶

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin中的并发与多线程:进阶篇



在现代开发中,高效的并发管理是创建快速响应式应用程序的关键。Kotlin凭借对协程(coroutines)的内置支持,提供了远超标准Java线程的强大而灵活的工具集。本文将探讨Kotlin中并发与多线程的高级概念,包括Channel、Flow、Mutex的使用以及调度器的细微差别。



1. 协程:超越基础



协程是轻量级线程,允许以命令式风格编写异步代码。然而在进阶层面,理解调度器(Dispatchers)和协程上下文的工作原理至关重要。



调度器(Dispatchers)

选择合适的调度器对性能至关重要:

  • Dispatchers.Default — 用于CPU密集型任务(默认使用与CPU核心数相等的线程池)。
  • Dispatchers.IO — 用于输入输出操作(网络、文件)。线程池可扩展至64个线程(或更多,取决于配置)。
  • Dispatchers.Main — 用于UI线程(Android、JavaFX)。
  • newSingleThreadContext 和 newFixedThreadPoolContext — 用于创建自定义线程池。


import kotlinx.coroutines.*

fun main() = runBlocking { launch(Dispatchers.Default) { println("CPU-bound task on ${Thread.currentThread().name}") } launch(Dispatchers.IO) { println("IO-bound task on ${Thread.currentThread().name}") }}


结构化并发

Kotlin的主要特性之一是结构化并发。它确保子协程在父协程完成之前完成。这可以防止内存泄漏并简化生命周期管理。



fun main() = runBlocking {    coroutineScope {        launch {            delay(1000)            println("Task 1 completed")        }        launch {            delay(500)            println("Task 2 completed")        }    }    println("All tasks completed")}


2. 通道(Channel):协程间数据传输



Channel是阻塞队列(BlockingQueue)的协程对应物。它允许在协程之间安全地传输数据,当通道满时挂起发送方,当通道空时挂起接收方。



通道类型

  • RendezvousChannel(默认)— 无缓冲区。发送会阻塞直到被接收。
  • BufferedChannel — 具有指定大小的缓冲区。
  • ConflatedChannel — 仅存储最后发送的值,覆盖之前的值。
  • UnlimitedChannel — 无限制缓冲区(注意:可能导致OOM)。


import kotlinx.coroutines.*import kotlinx.coroutines.channels.*

fun main() = runBlocking { val channel = Channel<Int>(capacity = 5) // Buffered channel

launch { for (i in 1..10) { channel.send(i) println("Sent: $i") } channel.close() }

launch { for (value in channel) { println("Received: $value") delay(100) } }}


扇出与扇入

通道非常适合"扇出"(一个生产者,多个消费者)和"扇入"(多个生产者,一个消费者)模式。



3. Flow:响应式数据流



与"热"数据流(无论是否有订阅者都会发送数据)的Channel不同,Flow是一种"冷"数据流,它

博客

书籍推荐