java重排序问题

java重排序现象

我们需要了解初始化对象的过程,大致如下:
1.分配内存空间
2.初始化对象
3.将对象指向分配的内存空间
有些编译器为了提升效率,会将2 3的顺序倒置(重排序,先将对象指向分配的内存空间再初始化),因此可能发生读取到未初始化完成的对象

下面看一个例子(这里不考虑多线程问题):
在这个例子中service方法判断bo对象是否为null,若不为null,获取attr属性,表面上看没有问题,若发生重排序现象,先将对象指向分配的内存空间,此时bo不为null,但attr属性的赋值工作有可能还未完成(假设需要很长时间),则获取到的值为null,遍历集合时就会出现空指针异常

public class Demo {
    
    private BO bo = new BO();
    
    public void service() {
        if(bo != null) {
            List<String> attrs = bo.getAttr();//若发生重排序,这里取到的值会是null
            attrs.stream().forEach(attr -> {
                //继续其他逻辑
            });
        }
    }
    
}

class BO{
    
    public List<String> attr;
    
    public BO() {
        attr = setAttr(); 
    }
    
    private List<String> setAttr() {
        //假设getAttrs是获取attr的方法
        return getAttrs();
    }
    
    public List<String> getAttr() {
        return this.attr;
    }
}

如何解决?
使用volatile关键字,禁止重排序

private volatile BO bo;

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理