synchronized → Coroutines

synchronized → Coroutines

老写法(Java --- synchronized 死锁)

scss 复制代码
// 线程 A
synchronized (lockA) {
    Thread.sleep(100);
    synchronized (lockB) {
        // 同时持有 lockA 和 lockB
    }
}

// 线程 B
synchronized (lockB) {
    Thread.sleep(100);
    synchronized (lockA) {
        // 同时持有 lockB 和 lockA --- 和线程 A 相反顺序,死锁
    }
}

问题在哪里

多个 synchronized 嵌套且获取锁的顺序不一致时,两个线程互相等待对方释放锁,形成死锁。JVM 不会自动检测和解决死锁,APP 直接卡死。

Android 中的常见死锁场景:主线程等待子线程结果 + 子线程等待主线程释放资源。

新写法(Kotlin Coroutines)

kotlin 复制代码
// 协程结构化并发 --- 避免锁竞争
suspend fun loadBoth() = coroutineScope {
    val resultA = async { loadA() }
    val resultB = async { loadB() }
    Result(resultA.await(), resultB.await())
}

// 需要用锁时 --- Mutex.withLock 有超时
private val mutexA = Mutex()
private val mutexB = Mutex()

suspend fun safeOperation() {
    mutexA.withLock {
        mutexB.withLock {
            // 两个锁都获取到了
        }
    }
}

一句话注意

协程的结构化并发是避免死锁的最佳方案------coroutineScope 保证并发任务全部完成或全部取消,不存在互相等待的锁依赖。async { } 启动子协程,await() 等待结果,整个过程不需要手动锁。

如果协程里确实需要锁,优先用单线程调度器(Dispatchers.Main + Dispatchers.IO 明确切换)消除竞争条件,而不是引入锁。最后的选择才是 Mutex------但用它时一定要保证加锁顺序一致。


Java Android 老项目迁移系列,持续更新中。

相关推荐
微尘寒风7 小时前
【Git】的安装和使用
java·git
y = xⁿ8 小时前
DeepSeek Harness 学习日记:关于Agent接口,工具调用的底层实现
android·java·学习
侧耳倾听1118 小时前
jwt使用简介
java·jwt
顶点多余9 小时前
那些在算法中适合巩固的知识点---1
java·前端·算法
AI人工智能+电脑小能手9 小时前
大白话说Java设计模式-46-责任链模式(业务实战篇)
java·设计模式·责任链模式·风控校验·servlet filter·spring interceptor·链式处理
jay神9 小时前
【计算机毕业设计】基于SpringBoot的程序教学辅助系统
java·前端·vue.js·spring boot·后端·毕业设计·课程设计
2601_9620664910 小时前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
yaoxin52112311 小时前
507. Java 反射 - 在 BeanFactory 中实现依赖注入
java·开发语言
OPEN-F11 小时前
C++模板教程:变参模板、折叠表达式与SFINAE
java·开发语言·c++
2601_9620722112 小时前
SpringMVC进阶(自定义拦截器以及异常处理)
java