侧边栏壁纸
博主头像
晓果冻博主等级

一个热爱生活的95后精神小伙

  • 累计撰写 131 篇文章
  • 累计创建 15 个标签
  • 累计收到 67 条评论

目 录CONTENT

文章目录

Java有序性案例

晓果冻
2022-08-08 / 1 评论 / 0 点赞 / 491 阅读 / 290 字
温馨提示:
本文最后更新于 2022-08-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Java有序性案例

  • 代码

    /**
     * @author 晓果冻
     */
    public class SingleInstance {
        
        private static SingleInstance instance;
        
        private SingleInstance(){};
        
        public static SingleInstance getInstance(){
            if(instance == null){
                synchronized (SingleInstance.class){
                    if(instance == null){
                        instance = new SingleInstance();
                    }
                }
            }
            return instance;
        }
    }
    
  • 执行流程
    image-20220803204741032

  • 顺序性问题点

    instance = new SingleInstance();//这行代码包括如下三个步骤
    
    1. 分配内存空间
    2. 初始化对象
    3. 将instance引用指向内存空间。

    正常执行顺序:1->2->3,但cpu指令重排后可能位1->3->2这种

  • 假设执行顺序:

    1. 线程A和线程B同时进入第一个if条件判断。
    2. A线程首先获取到synchronized锁,进入代码块,此时instance为null,所以执行instance=new SingleInstance()语句。
    3. 在执行instance = new SingleInstance();时,线程A在JVM开辟一块空白的内存空间。
    4. 线程A将instance引用指向空白的内存空间,在没有进行对象初始化时,发生了线程切换,线程A释放锁。
    5. 线程B拿到锁,发现instance不为null,但此时instance并未初始化,是一个空对象。如果线程B使用instance对象,可能就会出现问题。
  • image-20220808191300789

0

评论区