面试题答案
一键面试利用协程优化并发性能
- 使用协程构建并发任务:
- 在Kotlin中,可以使用
launch
函数来启动新的协程。例如,对于处理多个独立的请求,可以这样做:
val requests = listOf(/*请求数据*/) requests.forEach { request -> launch { // 处理请求的逻辑 val result = processRequest(request) // 处理结果 handleResult(result) } }
async
函数用于启动一个异步操作并返回一个Deferred
对象,可用于获取操作的结果。如果需要等待多个异步操作完成并收集结果,可以这样:
val deferreds = requests.map { request -> async { processRequest(request) } } val results = deferreds.map { it.await() }
- 在Kotlin中,可以使用
- 线程池的合理使用:
- 可以通过
Dispatchers
来指定协程运行的线程池。对于CPU密集型任务,使用Dispatchers.Default
,它使用共享的后台线程池,适用于计算量大的任务。对于I/O密集型任务,使用Dispatchers.IO
,它优化了I/O操作的线程使用。例如:
launch(Dispatchers.IO) { // I/O操作,如读取文件、数据库查询等 } launch(Dispatchers.Default) { // CPU密集型计算 }
- 可以通过
处理协程之间的资源竞争
- 使用
Mutex
:Mutex
(互斥锁)用于保护共享资源,确保同一时间只有一个协程可以访问该资源。例如,假设有一个共享的计数器:
private val mutex = Mutex() private var counter = 0 launch { mutex.lock() try { counter++ } finally { mutex.unlock() } }
Semaphore
的应用:Semaphore
用于限制同时访问某个资源的协程数量。比如,有一个数据库连接池,最大连接数为10,就可以使用Semaphore
来控制:
private val semaphore = Semaphore(10) launch { semaphore.acquire() try { // 使用数据库连接进行操作 } finally { semaphore.release() } }
死锁预防
- 资源获取顺序一致:
- 在多个协程需要获取多个资源时,确保所有协程以相同的顺序获取资源。例如,协程A和协程B都需要获取资源X和资源Y,那么都应该先获取资源X,再获取资源Y。
- 使用超时机制:
- 可以为资源获取操作设置超时。例如,使用
withTimeout
函数:
val success = withTimeoutOrNull(1000) { mutex.lock() try { // 处理共享资源 true } finally { mutex.unlock() } } if (!success) { // 处理获取资源超时的情况 }
- 可以为资源获取操作设置超时。例如,使用
合理的协程调度策略
- 优先级调度:
- 可以通过自定义调度器或使用
Job
的优先级来实现。例如,对于一些重要的请求,可以将其协程的优先级设置得更高。可以创建一个带有优先级的调度器:
class PriorityDispatcher(private val priority: Int) : ExecutorCoroutineDispatcher() { override fun newSingleThreadContext(name: String): ExecutorCoroutineContext.Element = Executors.newSingleThreadExecutor { r -> val thread = Thread(r) thread.priority = priority thread }.asCoroutineDispatcher() } val highPriorityDispatcher = PriorityDispatcher(Thread.MAX_PRIORITY) launch(highPriorityDispatcher) { // 高优先级任务 }
- 可以通过自定义调度器或使用
- 动态调整协程数量:
- 根据系统的负载情况动态调整协程的数量。可以通过监控CPU使用率、内存使用率等指标,当系统负载过高时,减少新启动的协程数量,当负载降低时,适当增加协程数量。例如,可以使用
Semaphore
来控制并发协程的数量,并根据系统指标动态调整Semaphore
的许可数量。
- 根据系统的负载情况动态调整协程的数量。可以通过监控CPU使用率、内存使用率等指标,当系统负载过高时,减少新启动的协程数量,当负载降低时,适当增加协程数量。例如,可以使用