You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中synchronized块后的also块是否存在并发变量安全问题

结论

不会出现你担心的it变量在执行logger.log前被其他线程修改的问题。

核心原因
  • 先理清楚这段代码的严格执行顺序:
    1. 线程跑到synchronized(this)时先争抢this的监视器锁,拿到锁才会执行块内逻辑,最终生成你要的String结果
    2. 同步块内所有逻辑跑完,会先把生成的String作为同步块的返回值固定存到当前线程的操作数栈,之后才会执行锁释放动作
    3. 锁完全释放后,才会调用.also方法,把之前已经存好的String引用作为参数传入lambda,也就是你代码里的it
  • 从变量存储特性看:it是每个线程执行这段代码时,在自己的调用栈帧上生成的局部临时变量,属于线程私有的数据,其他线程根本没有访问这个局部变量的入口,完全不可能修改它的值。
  • 还有两层额外保障:
    1. 你这里同步块返回的是String类型,Kotlin/Java里的String本身就是不可变类,就算其他线程凑巧拿到同一个String的引用,也改不了字符串的内容
    2. Kotlin里lambda的隐式参数it默认是final修饰的,别说其他线程,当前执行的线程自己都没法在also块里给it重新赋值。
容易踩的认知误区

不少人误以为also块写在synchronized括号外面,就会因为锁提前释放导致变量被篡改,实际上同步块的返回值是在持锁阶段就已经计算完成、完成值传递的,锁释放动作根本碰不到已经确定的返回值。
唯一可能出现可见性问题的场景是:你同步块返回的是可变对象(比如自定义可变类、ArrayList这类非线程安全的集合),且其他线程持有这个对象的引用去修改它的内部属性——但这时候改的是堆上对象的内部内容,不是it变量本身存的引用值,和你问的“it变量被修改”完全是两个概念。

内容的提问来源于stack exchange,提问作者Milad Amery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:49:12