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

Spring组件多线程读写时,引用赋值需加锁吗?引用赋值是否原子?

问题解答

1. 对象引用赋值的原子性

Java中对象引用的赋值操作是原子操作。比如你代码里的listFromDynamo = result;,多线程环境下不会出现"半赋值"的中间状态——读线程要么拿到旧的List引用,要么拿到新的List引用,不会获取到无效的部分赋值状态。

注意:原子性仅保证引用赋值本身的完整性,不涉及List内部元素的可见性和指令有序性。

2. 当前场景是否需要并发锁?

不需要额外加锁,但要做一处小修改保证线程安全:

为什么不需要锁?

你的更新逻辑是先在写线程本地创建全新的ArrayList,完成DynamoDB数据填充后,再将新List的引用赋值给listFromDynamo。读线程完全看不到新List的填充过程,只会拿到完整的旧List或完整的新List,不会读到部分填充的无效List。

必须的修改:保证可见性

虽然赋值是原子的,但默认情况下读线程可能缓存listFromDynamo的旧值,无法及时感知到写线程的更新。需要给listFromDynamo添加volatile关键字:

private volatile List<ClassFromDyanmo> listFromDynamo;

volatile的作用:

  • 禁止指令重排序,确保写线程的赋值操作完成后才会被读线程感知
  • 保证变量的可见性,写线程修改后,读线程能立即获取到最新引用

额外优化建议

  • 可以把返回的List设置为不可变,避免读线程误修改List内容(防御性编程):
    在updateListFromDynamo方法最后转换为不可变List:
    listFromDynamo = Collections.unmodifiableList(result);
    
    或者在getListFromDynamo方法中返回不可变版本:
    public List<ClassFromDyanmo> getListFromDynamo() {
        return Collections.unmodifiableList(listFromDynamo);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:35:20