前言:我知道在大多数情况下,使用 volatile 字段不会产生任何可测量的性能损失,但这个问题更具理论性,并且针对具有极高准确性支持的设计。
我有一个字段,List<Something>
它是在构造后填充的。为了节省一些性能,我想将列表转换为只读地图。在任何时候这样做都需要至少一个可变的 Map 字段,因此使所有线程的更改可见。
我正在考虑执行以下操作:
地图地图; 公共无效获取(对象键){ 如果(地图==空){ 地图临时=新地图(); for(对象值: super.getList()){ temp.put(value.getKey(),value); } 地图=温度; } 返回 map.get(key); }
这可能会导致多个线程生成映射,即使它们以序列化方式进入 get 块。如果线程在地图的不同相同实例上工作,这将不是什么大问题。更让我担心的是:
是否有可能一个线程将新的临时映射分配给映射字段,然后第二个线程看到它map!=null
并因此访问映射字段而不生成新的,但令我惊讶的是发现映射是空的,因为 put 操作哪里还没有推送到某个共享内存区域?
评论回复:
- 线程仅在只读之后修改临时映射。
- 由于一些特殊的 JAXB 设置,我必须将 List 转换为 Map,这使得从 Map 开始变得不可行。