Android 协程全景式深度解析:第六章 高阶并发模式

6.1 Actor模型实现

6.1.1 Actor概念解析

Actor模型是一种并发计算模型,核心思想是:

  • 封装状态:每个Actor维护私有状态
  • 消息驱动:通过消息传递进行通信
  • 顺序处理:每次只处理一个消息
  • 位置透明:Actor位置对调用者透明

6.1.2 Kotlin Actor实现

基础Actor实现:

kotlin 复制代码
// 使用Channel实现Actor
class UserActor : CoroutineScope {
    private val job = Job()
    override val coroutineContext = job + Dispatchers.Default
    
    // Actor邮箱(通道)
    private val mailbox = Channel<UserEvent>(capacity = Channel.UNLIMITED)
    
    // 私有状态
    private var userState: UserState = UserState.Initial
    
    init {
        // 启动消息处理
        launch {
            for (event in mailbox) {
                processEvent(event)
            }
        }
    }
    
    // 处理事件(顺序执行)
    private fun processEvent(event: UserEvent) {
        when (event) {
            is Login -> {
                userState = UserState.LoggedIn(event.user)
                saveSession(event.user)
            }
            is Logout -> {
                userState = UserState.LoggedOut
                clearSession()
            }
            is UpdateProfile -> {
                if (userState is UserState.LoggedIn) {
                    updateUserProfile(event.profile)
                }
            }
        }
    }
    
    // 外部发送消息接口
    suspend fun send(event: UserEvent) {
        mailbox.send(event)
    }
    
    // 关闭Actor
    fun close() {
        mailbox.close()
        job.cancel()
    }
}

使用场景:

kotlin 复制代码
// 在ViewModel中管理用户状态
class UserViewModel : ViewModel() {
    private val userActor = UserActor()
    
    fun login(user: User) {
        viewModelScope.launch {
            userActor.send(Login(user))
        }
    }
    
    fun logout() {
        viewModelScope.launch {
            userActor.send(Logout)
        }
    }
    
    override fun onCleared() {
        super.onCleared()
        userActor.close()
    }
}

6.1.3 高级Actor模式

带状态查询的Actor:

kotlin 复制代码
// 支持查询的Actor
class QueryableUserActor : CoroutineScope {
    // ... 同基础实现 ...
    
    // 查询状态接口
    suspend fun getState(): UserState = withContext(coroutineContext) {
        // 使用CompletableDeferred获取结果
        val result = CompletableDeferred<UserState>()
        
        // 发送查询消息
        mailbox.send(GetState(result))
        
        // 等待结果
        result.await()
    }
    
    private fun processEvent(event: UserEvent) {
        when (event) {
            // ... 其他事件 ...
            is GetState -> {
                // 直接返回当前状态
                event.result.complete(userState)
            }
        }
    }
}

// 查询消息定义
private class GetState(val result: CompletableDeferred<UserState>) : UserEvent

错误处理Actor:

kotlin 复制代码
class ErrorHandlingActor : CoroutineScope {
    // ... 同基础实现 ...
    
    private fun processEvent(event: UserEvent) {
        try {
            when (event) {
                // ... 事件处理 ...
            }
        } catch (e: Exception) {
            // 错误恢复逻辑
            recoverFromError(e)
        }
    }
    
    private fun recoverFromError(e: Exception) {
        // 1. 记录错误
        logError(e)
        
        // 2. 重置到安全状态
        resetToSafeState()
        
        // 3. 通知监控系统
        notifyMonitoringSystem(e)
    }
}

6.2 复杂管道设计

6.2.1 多阶段处理管道

实现代码:

kotlin 复制代码
// 创建数据处理管道
fun createDataPipeline(): ReceiveChannel<ProcessedData> = produce {
    // 阶段1: 数据清洗
    val cleaned = cleanData(rawDataChannel)
    
    // 阶段2: 数据验证
    val validated = validateData(cleaned)
    
    // 阶段3: 数据转换
    val transformed = transformData(validated)
    
    // 阶段4: 数据存储
    storeData(transformed).consumeEach { result ->
        send(result) // 发送处理结果
    }
}

// 清洗阶段
private suspend fun cleanData(source: ReceiveChannel<RawData>): ReceiveChannel<CleanedData> = 
    produce {
        for (data in source) {
            send(clean(data))
        }
    }

// 使用管道
viewModelScope.launch {
    val pipeline = createDataPipeline()
    pipeline.consumeEach { processedData ->
        // 显示处理结果
        updateUI(processedData)
    }
}

6.2.2 分支与合并管道

scss 复制代码
// 复杂分支管道
fun createComplexPipeline(): Flow<Result> = callbackFlow {
    // 主数据源
    val mainSource = dataSourceFlow()
    
    // 分支1: 并行处理A
    val branchA = mainSource
        .map { processBranchA(it) }
        .catch { /* 错误处理 */ }
    
    // 分支2: 并行处理B
    val branchB = mainSource
        .flatMapMerge { processBranchB(it) }
    
    // 合并结果
    merge(branchA, branchB)
        .collect { send(it) } // 发送到回调流
}

// 使用
viewModelScope.launch {
    createComplexPipeline()
        .buffer(100) // 防止背压
        .collect { result ->
            // 处理合并结果
        }
}

6.3 资源竞争解决方案

6.3.1 Mutex(互斥锁)

基础使用:

kotlin 复制代码
private val mutex = Mutex()

suspend fun safeIncrement() {
    mutex.withLock {
        // 临界区代码
        sharedCounter++
    }
}

// 使用示例
repeat(1000) {
    launch {
        safeIncrement()
    }
}

源码解析:

kotlin 复制代码
// Mutex.kt 核心实现
public class MutexImpl() : Mutex {
    // 等待队列
    private val queue = LockFreeLinkedListHead()
    
    override suspend fun lock(owner: Any?) {
        // 尝试立即获取锁
        if (tryLock(owner)) return
        
        // 创建等待节点
        val node = LockWaiter(owner)
        while (true) {
            queue.addLast(node)
            if (tryLock(owner)) {
                node.remove()
                return
            }
            // 挂起等待
            node.await()
        }
    }
    
    override fun unlock(owner: Any?) {
        // 释放锁并唤醒下一个等待者
        queue.removeFirstOrNull()?.resume()
    }
}

6.3.2 Semaphore(信号量)

限流访问资源:

scss 复制代码
// 限制5个并发访问
private val semaphore = Semaphore(5)

suspend fun accessLimitedResource() {
    semaphore.withPermit {
        // 访问受限资源
        fetchDataFromAPI()
    }
}

// 使用
repeat(20) {
    launch {
        accessLimitedResource()
    }
}

自定义信号量实现:

kotlin 复制代码
class CustomSemaphore(permits: Int) {
    private val mutex = Mutex()
    private var available = permits
    private val waiters = mutableListOf<CompletableDeferred<Unit>>()
    
    suspend fun acquire() {
        mutex.withLock {
            if (available > 0) {
                available--
                return
            }
            // 无可用许可,等待
            val waiter = CompletableDeferred<Unit>()
            waiters.add(waiter)
            mutex.unlock()
            waiter.await() // 挂起等待
            mutex.lock()
            available-- // 获取许可
        }
    }
    
    fun release() {
        mutex.withLock {
            available++
            if (waiters.isNotEmpty()) {
                // 唤醒一个等待者
                val waiter = waiters.removeAt(0)
                waiter.complete(Unit)
            }
        }
    }
}

6.4 结构化并发进阶

6.4.1 嵌套作用域管理

实现代码:

scss 复制代码
suspend fun processComplexTask() = coroutineScope {
    // 任务组1
    val group1 = async {
        // 子任务1.1
        val task1 = async { fetchDataFromSource1() }
        // 子任务1.2
        val task2 = async { fetchDataFromSource2() }
        Pair(task1.await(), task2.await())
    }
    
    // 任务组2
    val group2 = async {
        // 子任务2.1
        val task1 = async { processDataPart1() }
        // 子任务2.2
        val task2 = async { processDataPart2() }
        combineResults(task1.await(), task2.await())
    }
    
    // 合并结果
    Result(group1.await(), group2.await())
}

6.4.2 超时控制模式

带超时的资源获取:

kotlin 复制代码
suspend fun fetchDataWithTimeout(): Data {
    // 尝试在500ms内获取数据
    return withTimeoutOrNull(500) {
        apiService.fetchData()
    } ?: throw TimeoutException("Data fetch timed out")
}

// 复杂任务超时控制
suspend fun executeComplexTask() {
    try {
        withTimeout(3000) {
            // 启动多个并行任务
            val task1 = async { step1() }
            val task2 = async { step2() }
            
            // 等待所有任务完成
            awaitAll(task1, task2)
            
            // 执行最终步骤
            finalStep()
        }
    } catch (e: TimeoutCancellationException) {
        // 超时处理
        handleTimeout()
    }
}

6.5 并行处理模式

6.5.1 分治策略

kotlin 复制代码
// 使用分治策略处理大数据集
suspend fun processLargeDataSet(data: List<Data>): Result = supervisorScope {
    if (data.size < 1000) {
        // 小数据集直接处理
        return@supervisorScope processChunk(data)
    }
    
    // 分割数据集
    val mid = data.size / 2
    val left = data.subList(0, mid)
    val right = data.subList(mid, data.size)
    
    // 并行处理子集
    val leftDeferred = async { processLargeDataSet(left) }
    val rightDeferred = async { processLargeDataSet(right) }
    
    // 合并结果
    mergeResults(leftDeferred.await(), rightDeferred.await())
}

6.5.2 并行集合处理

kotlin 复制代码
// 并行处理列表
suspend fun <T, R> List<T>.parallelMap(
    concurrencyLevel: Int = 10,
    transform: suspend (T) -> R
): List<R> = coroutineScope {
    val channel = Channel<Pair<Int, R>>(Channel.UNLIMITED)
    val results = arrayOfNulls<Any?>(size)
    
    // 启动处理协程
    repeat(concurrencyLevel) {
        launch {
            for ((index, item) in this@parallelMap.withIndex()) {
                val result = transform(item)
                channel.send(index to result)
            }
        }
    }
    
    // 收集结果
    launch {
        repeat(size) {
            val (index, result) = channel.receive()
            results[index] = result
        }
        channel.close()
    }
    
    // 等待完成
    (results as Array<R>).toList()
}

// 使用示例
val processedData = largeList.parallelMap { item ->
    heavyProcessing(item)
}

6.6 容错与重试策略

6.6.1 指数退避重试

kotlin 复制代码
// 带指数退避的重试机制
suspend fun <T> retryWithBackoff(
    times: Int = 3,
    initialDelay: Long = 100,
    maxDelay: Long = 1000,
    factor: Double = 2.0,
    block: suspend () -> T
): T {
    var currentDelay = initialDelay
    repeat(times) { attempt ->
        try {
            return block()
        } catch (e: Exception) {
            if (attempt == times - 1) throw e
            
            // 计算下次延迟
            val nextDelay = (currentDelay * factor).toLong()
            currentDelay = nextDelay.coerceAtMost(maxDelay)
            
            // 延迟后重试
            delay(currentDelay)
        }
    }
    throw IllegalStateException("Unreachable")
}

// 使用
val result = retryWithBackoff {
    apiService.fetchData()
}

6.6.2 熔断器模式

kotlin 复制代码
class CircuitBreaker(
    private val failureThreshold: Int = 5,
    private val resetTimeout: Long = 60000
) {
    private var state: State = State.CLOSED
    private var failureCount = 0
    private var lastFailureTime: Long = 0
    private val mutex = Mutex()
    
    sealed class State {
        object CLOSED : State()
        object OPEN : State()
        object HALF_OPEN : State()
    }
    
    suspend fun <T> protect(block: suspend () -> T): T {
        mutex.withLock {
            if (state == State.OPEN) {
                val currentTime = System.currentTimeMillis()
                if (currentTime - lastFailureTime > resetTimeout) {
                    state = State.HALF_OPEN
                } else {
                    throw CircuitBreakerOpenException()
                }
            }
        }
        
        return try {
            val result = block()
            mutex.withLock {
                if (state == State.HALF_OPEN) {
                    // 成功则关闭熔断器
                    state = State.CLOSED
                    failureCount = 0
                }
            }
            result
        } catch (e: Exception) {
            mutex.withLock {
                failureCount++
                if (failureCount >= failureThreshold || state == State.HALF_OPEN) {
                    state = State.OPEN
                    lastFailureTime = System.currentTimeMillis()
                }
            }
            throw e
        }
    }
}

// 使用
private val circuitBreaker = CircuitBreaker()

suspend fun safeCall() {
    circuitBreaker.protect {
        apiService.unstableEndpoint()
    }
}

本章小结

本章深入探讨了协程的高阶并发模式:

  1. Actor模型:封装状态、消息驱动的并发单元
  2. 复杂管道:多阶段处理与分支合并架构
  3. 资源竞争:Mutex与Semaphore的深度应用
  4. 结构化并发:嵌套作用域与超时控制
  5. 并行处理:分治策略与并行集合操作
  6. 容错机制:指数退避重试与熔断器模式
相关推荐
_一条咸鱼_36 分钟前
Vulkan入门教程:源码级解析
android·面试·android jetpack
嘉小华38 分钟前
ThreadLocal 详解
android
wkj0011 小时前
php 如何通过mysqli操作数据库?
android·数据库·php
kymjs张涛3 小时前
零一开源|前沿技术周报 #7
android·前端·ios
wuwu_q5 小时前
RK3566/RK3568 Android11 修改selinux模式
android·rk3568
_一条咸鱼_5 小时前
Android Runtime内存共享与访问控制原理剖析(71)
android·面试·android jetpack
嘉小华6 小时前
第三章:焦点分发全链路源码解析
android
嘉小华6 小时前
Android 协程全景式深度解析:第七章 协程调试与性能优化
android
你过来啊你6 小时前
Android开发中RxJava的使用与原理
android